ATLAS Offline Software
Loading...
Searching...
No Matches
TrigAFPDijetComboHypoTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4
6
8#include "xAODJet/Jet.h"
9
12
15#include <math.h>
16
17TrigAFPDijetComboHypoTool::TrigAFPDijetComboHypoTool(const std::string& type, const std::string& name, const IInterface* parent)
18 : ComboHypoToolBase(type, name, parent),
19 m_transportBeamA("AFPProtonTransportTool/TransportBeamA", this),
20 m_transportBeamC("AFPProtonTransportTool/TransportBeamC", this)
21{
22 declareProperty("TransportBeamA",m_transportBeamA,"Proton transport tool side A");
23 declareProperty("TransportBeamC",m_transportBeamC,"Proton transport tool side C");
24}
25
29
31 ATH_MSG_INFO("Initialization. The correct configuration of this algorithm "
32 << "requires jets ordered in increasing energy");
33
34 // Initialize collections
36
37 if (!(m_monTool.name().empty())) {
38 ATH_CHECK( m_monTool.retrieve() );
39 ATH_MSG_DEBUG("m_monTool name: " << m_monTool);
40 }
41
42 if(!(m_transportBeamA.name().empty())){
43 ATH_CHECK( m_transportBeamA.retrieve() );
44 ATH_MSG_DEBUG("m_transportBeamA name: " << m_transportBeamA);
45 }
46
47 if(!(m_transportBeamC.name().empty())){
48 ATH_CHECK( m_transportBeamC.retrieve() );
49 ATH_MSG_DEBUG("m_transportBeamC name: " << m_transportBeamC);
50 }
51
52 //Retrieving the parameterization file for A side
53 // By default it used file final_parameterization_b1.txt
54 ATH_MSG_DEBUG("Parameterization file for A side: "<< m_protonTransportParamFileNameA);
55 const std::string filePathA = PathResolver::find_file(m_protonTransportParamFileNameA, "DATAPATH");
56 ATH_MSG_DEBUG("Path to param file side A: "<<filePathA);
57 //Defining the parameterization object
58 m_transportBeamA->setParamFile(filePathA);
60
61 //Retrieving the parameterization file for C side
62 // By default it used file final_parameterization_b2.txt
63 ATH_MSG_DEBUG("Parameterization file for C side: "<< m_protonTransportParamFileNameC);
64 const std::string filePathC = PathResolver::find_file(m_protonTransportParamFileNameC, "DATAPATH");
65 ATH_MSG_DEBUG("Path to param file side C: "<<filePathC);
66 //Defining the parameterization object
67 m_transportBeamC->setParamFile(filePathC);
69
70 return StatusCode::SUCCESS;
71}
72
73struct DescendingEt {
74 bool operator () (const xAOD::Jet* l, const xAOD::Jet* r) const {
75 return l->p4().Et() > r->p4().Et();
76 }
77};
78
79bool TrigAFPDijetComboHypoTool::executeAlg(const std::vector<Combo::LegDecision>& combination,
80 const EventContext& ctx) const {
81
82 ATH_MSG_DEBUG("TrigAFPDijetComboHypoTool::executeAlg Executing algorithm");
83
84 std::vector<ElementLink<xAOD::JetContainer>> selected_jets;
85
86 // Expecting to run over chains with the signature HLT_afp_2jX, and hence to be supplied with three Decision Objects for each combination.
87 if(combination.size() != 3) ATH_MSG_ERROR("Number of leg decisions is not 3!");
88
89 // One of these is the AFP Decision Object, which we ignore as we are fetching the AFP reconstruction directly from a ReadHandle.
90 // The other two should be Jet Decision Objects.
91 for(const auto& comb: combination){
92 const auto dec = comb.second;
94 if (jet_link.isValid()) {
95 selected_jets.push_back(jet_link);
96 }
97 }
98
99 if(selected_jets.size() != 2){
100 ATH_MSG_ERROR("Expecting to combine exactly two jets, but instead found "
101 << selected_jets.size() << ". Will throw a runtime error");
102 throw std::runtime_error(
103 "Expecting to combine exactly two jets, but instead found " +
104 std::to_string(selected_jets.size()));
105 }
106
107 // Get jet pair
108 auto jetLink1 = selected_jets[0]; // Need to check if jets are actually ordered in pT
109 auto jetLink2 = selected_jets[1];
110
111 TLorentzVector jet1_vec = (*jetLink1)->p4();
112 TLorentzVector jet2_vec = (*jetLink2)->p4();
113 TLorentzVector dijet = jet1_vec + jet2_vec;
114
115 // Calculate dijet quantities
116 auto dijetMass = Monitored::Scalar( "DijetMass" , -999.0 );
117 auto dijetRapidity = Monitored::Scalar( "DijetRapidity" , -999.0 );
118 dijetMass = dijet.M() * m_GeV;
119 ATH_MSG_DEBUG("AFP ComboHypo::DijetMass "<<dijetMass);
120 dijetRapidity = dijet.Rapidity();
121 Monitored::fill(m_monTool, dijetMass);
122 Monitored::fill(m_monTool, dijetRapidity);
123
124 // Calculate relative energy loos
125 auto xiJet1 = Monitored::Scalar( "XiJet1" , -999.0 );
126 auto xiJet2 = Monitored::Scalar( "XiJet2" , -999.0 );
127 xiJet1 = exp(dijetRapidity) * dijetMass / m_totalEnergy;
128 xiJet2 = exp(-dijetRapidity) * dijetMass / m_totalEnergy;
129 Monitored::fill(m_monTool, xiJet1);
130 Monitored::fill(m_monTool, xiJet2);
131
132 // Predict proton positions on AFP sides A and C
133 auto predictProtonAEnergy = Monitored::Scalar( "PredictProtonAEnergy" , -999.0 );
134 auto predictProtonCEnergy = Monitored::Scalar( "PredictProtonCEnergy" , -999.0 );
135 predictProtonAEnergy = m_beamEnergy * (1. - xiJet1); // Side A
136 predictProtonCEnergy = m_beamEnergy * (1. - xiJet2); // Side C
137 Monitored::fill(m_monTool, predictProtonAEnergy);
138 Monitored::fill(m_monTool, predictProtonCEnergy);
139
140 // Side A position prediction
141 auto sideA_predictX = Monitored::Scalar( "SideA_predictX" , -999.0 );
142 auto sideA_predictY = Monitored::Scalar( "SideA_predictY" , -999.0 );
143 sideA_predictX = 1e3 * m_transportBeamA->x(0, 0, 0, 0, 0, predictProtonAEnergy) + m_protonPosShift_x;
144 sideA_predictY = 1e3 * m_transportBeamA->x(0, 0, 0, 0, 0, predictProtonAEnergy) + m_protonPosShift_y;
145 Monitored::fill(m_monTool, sideA_predictX);
146 Monitored::fill(m_monTool, sideA_predictY);
147
148 // Side C position prediction
149 auto sideC_predictX = Monitored::Scalar( "SideC_predictX" , -999.0 );
150 auto sideC_predictY = Monitored::Scalar( "SideC_predictY" , -999.0 );
151 sideC_predictX = 1e3 * m_transportBeamC->x(0, 0, 0, 0, 0, predictProtonCEnergy) + m_protonPosShift_x;
152 sideC_predictY = 1e3 * m_transportBeamC->x(0, 0, 0, 0, 0, predictProtonCEnergy) + m_protonPosShift_y;
153 Monitored::fill(m_monTool, sideC_predictX);
154 Monitored::fill(m_monTool, sideC_predictY);
155
156 // Retrieve AFP track container
158
159 double sideA_minDist = 9e9;
160 double sideC_minDist = 9e9;
161
162 int nearestTrackSideAId = 999;
163 int nearestTrackSideCId = 999;
164
165 auto xDiff = Monitored::Scalar("XDiff",-999.0);
166 auto yDiff = Monitored::Scalar("YDiff",-999.0);
167 auto distance = Monitored::Scalar("distance",-999.0);
168
169 // Find nearest track
170 for(auto track: (*tracksAFP)){
171
172 xDiff = -999.0;
173 yDiff = -999.0;
174 distance = -999.0;
175
176 // Side A
177 if(track->stationID() == 1){
178
179 xDiff = sideA_predictX - (track->xLocal() + m_alignmentCorrection_nearA);
180 yDiff = sideA_predictY - track->yLocal();
181 distance = sqrt(xDiff * xDiff + yDiff * yDiff);
182
183 if(distance < sideA_minDist){
184 sideA_minDist = distance;
185 nearestTrackSideAId = track->index();
186 }
187
188 }else if(track->stationID() == 2){
189
190 xDiff = sideC_predictX - (track->xLocal() + m_alignmentCorrection_nearC);
191 yDiff = sideC_predictY - track->yLocal();
192 distance = sqrt(xDiff * xDiff + yDiff * yDiff);
193
194 if(distance < sideC_minDist){
195 sideC_minDist = distance;
196 nearestTrackSideCId = track->index();
197 }
198 }// End of if for choosing AFP station
199
202 Monitored::fill(m_monTool, distance);
203
204 }// End of loop over AFP track
205
206 bool passRCutA = false;
207 bool passRCutC = false;
208
209 bool passXYCutA = false;
210 bool passXYCutC = false;
211
212 auto sideA_trackX = Monitored::Scalar("SideA_trackX",-999.0);
213 auto sideA_trackY = Monitored::Scalar("SideA_trackY",-999.0);
214 auto sideA_diffX = Monitored::Scalar("SideA_diffX",-999.0);
215 auto sideA_diffY = Monitored::Scalar("SideA_diffY",-999.0);
216
217 auto sideC_trackX = Monitored::Scalar("SideC_trackX",-999.0);
218 auto sideC_trackY = Monitored::Scalar("SideC_trackY",-999.0);
219 auto sideC_diffX = Monitored::Scalar("SideC_diffX",-999.0);
220 auto sideC_diffY = Monitored::Scalar("SideC_diffY",-999.0);
221
222 // Cuts on A side
223 if(nearestTrackSideAId != 999){
224
225 sideA_trackX = tracksAFP.get()->at(nearestTrackSideAId)->xLocal() + m_alignmentCorrection_nearA;
226 sideA_trackY = tracksAFP.get()->at(nearestTrackSideAId)->yLocal();
227 sideA_diffX = sideA_predictX - sideA_trackX;
228 sideA_diffY = sideA_predictY - sideA_trackY;
229
230 ATH_MSG_DEBUG("TrigAFPDijetComboHypoTool::execute sideA_diffX: " << sideA_diffX);
231
232 if(sideA_minDist < m_maxProtonDist) passRCutA = true;
233
234 if(fabs(sideA_diffX) < m_maxProtonDiff_x && fabs(sideA_diffY) < m_maxProtonDiff_y) passXYCutA = true;
235
236 }else{
237 passRCutA = false;
238 passXYCutA = false;
239 }
240
241 // Cuts on C side
242 if(nearestTrackSideCId != 999){
243
244 sideC_trackX = tracksAFP.get()->at(nearestTrackSideCId)->xLocal() + m_alignmentCorrection_nearC;
245 sideC_trackY = tracksAFP.get()->at(nearestTrackSideCId)->yLocal();
246 sideC_diffX = sideC_predictX - sideC_trackX;
247 sideC_diffY = sideC_predictY - sideC_trackY;
248
249 if(sideC_minDist < m_maxProtonDist) passRCutC = true;
250
251 if(fabs(sideC_diffX) < m_maxProtonDiff_x && fabs(sideC_diffY) < m_maxProtonDiff_y) passXYCutC = true;
252
253 }else{
254 passRCutC = false;
255 passXYCutC = false;
256 }
257
258 Monitored::fill(m_monTool,sideA_trackX);
259 Monitored::fill(m_monTool,sideA_trackY);
260 Monitored::fill(m_monTool,sideA_diffX);
261 Monitored::fill(m_monTool,sideA_diffY);
262
263 Monitored::fill(m_monTool,sideC_trackX);
264 Monitored::fill(m_monTool,sideC_trackY);
265 Monitored::fill(m_monTool,sideC_diffX);
266 Monitored::fill(m_monTool,sideC_diffY);
267
268 bool pass = false;
269
270 if(passRCutA && passRCutC && passXYCutA && passXYCutC) pass = true;
271
272 return pass;
273
274}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
ComboHypoToolBase(const std::string &type, const std::string &name, const IInterface *parent)
Declare a monitored scalar variable.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
ToolHandle< IAFPProtonTransportTool > m_transportBeamA
Gaudi::Property< float > m_protonPosShift_x
Shift in x position between parameterization and measurements.
virtual StatusCode initialize() override
virtual bool executeAlg(const std::vector< Combo::LegDecision > &combination, const EventContext &ctx) const override
Only a dummy implementation exists in ComboHypoToolBase.
const float m_GeV
Variable to convert from MeV to GeV.
Gaudi::Property< float > m_maxProtonDiff_y
Threshold for the y distance between parameterization and measurements.
Gaudi::Property< std::string > m_protonTransportParamFileNameC
Gaudi::Property< float > m_maxProtonDiff_x
Threshold for the x distance between parameterization and measurements.
Gaudi::Property< float > m_maxProtonDist
Threshold for the radius distance between parameterization and measurements.
SG::ReadHandleKey< xAOD::AFPTrackContainer > m_AFPtrackCollectionReadKey
Gaudi::Property< float > m_alignmentCorrection_nearA
Beam alignment corrections in the x position of ATLAS A side.
float m_totalEnergy
beams centre-of-mass energy 2*m_beamEnergy
Gaudi::Property< float > m_protonPosShift_y
Shif in y position between parameterization and measurements.
Gaudi::Property< float > m_beamEnergy
energy of one beam i.e. half of centre-of-mass energy
ToolHandle< IAFPProtonTransportTool > m_transportBeamC
Proton transport parameterizaton object used in the proton position prediction for ATLAS C side.
ToolHandle< GenericMonitoringTool > m_monTool
TrigAFPDijetComboHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< float > m_alignmentCorrection_nearC
Beam alignment corrections in the x position of ATLAS C side.
Gaudi::Property< std::string > m_protonTransportParamFileNameA
Boolean corresponding to the decision to record the event based on the selection being met.
int r
Definition globals.cxx:22
void fill(const ToolHandle< GenericMonitoringTool > &tool, T &&... variables)
const std::string & featureString()
LinkInfo< T > findLink(const Decision *start, const std::string &linkName, const bool suppressMultipleLinksWarning=false)
Perform a recursive search for ElementLinks of type T and name 'linkName', starting from Decision obj...
Jet_v1 Jet
Definition of the current "jet version".
bool operator()(const xAOD::Photon *l, const xAOD::Photon *r) const