ATLAS Offline Software
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 
7 #include "xAODJet/JetContainer.h"
8 #include "xAODJet/Jet.h"
9 
11 #include "xAODForward/AFPTrack.h"
12 
15 #include <math.h>
16 
17 TrigAFPDijetComboHypoTool::TrigAFPDijetComboHypoTool(const std::string& type, const std::string& name, const IInterface* 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 
27 {
28 }
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);
59  ATH_CHECK(m_transportBeamA->load());
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);
68  ATH_CHECK(m_transportBeamC->load());
69 
70  return StatusCode::SUCCESS;
71 }
72 
73 struct DescendingEt {
74  bool operator () (const xAOD::Jet* l, const xAOD::Jet* r) const {
75  return l->p4().Et() > r->p4().Et();
76  }
77 };
78 
79 bool 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;
93  const auto jet_link = TrigCompositeUtils::findLink<xAOD::JetContainer>(*dec, TrigCompositeUtils::featureString()).link;
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 
200  Monitored::fill(m_monTool, xDiff);
201  Monitored::fill(m_monTool, yDiff);
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 }
TrigAFPDijetComboHypoTool::m_transportBeamA
ToolHandle< IAFPProtonTransportTool > m_transportBeamA
Definition: TrigAFPDijetComboHypoTool.h:43
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtils.h:420
TrigAFPDijetComboHypoTool::m_AFPtrackCollectionReadKey
SG::ReadHandleKey< xAOD::AFPTrackContainer > m_AFPtrackCollectionReadKey
Definition: TrigAFPDijetComboHypoTool.h:70
beamspotman.r
def r
Definition: beamspotman.py:672
AFPTrackContainer.h
Jet.h
TrigAFPDijetComboHypoTool::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: TrigAFPDijetComboHypoTool.h:73
TrigAFPDijetComboHypoTool::m_maxProtonDiff_x
Gaudi::Property< float > m_maxProtonDiff_x
Threshold for the x distance between parameterization and measurements.
Definition: TrigAFPDijetComboHypoTool.h:50
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TrigAFPDijetComboHypoTool::m_protonPosShift_x
Gaudi::Property< float > m_protonPosShift_x
Shift in x position between parameterization and measurements.
Definition: TrigAFPDijetComboHypoTool.h:58
TrigAFPDijetComboHypoTool::~TrigAFPDijetComboHypoTool
virtual ~TrigAFPDijetComboHypoTool()
Definition: TrigAFPDijetComboHypoTool.cxx:26
TrigAFPDijetComboHypoTool::m_protonPosShift_y
Gaudi::Property< float > m_protonPosShift_y
Shif in y position between parameterization and measurements.
Definition: TrigAFPDijetComboHypoTool.h:60
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
TrigAFPDijetComboHypoTool::initialize
virtual StatusCode initialize() override
Definition: TrigAFPDijetComboHypoTool.cxx:30
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:157
TrigAFPDijetComboHypoTool::m_protonTransportParamFileNameA
Gaudi::Property< std::string > m_protonTransportParamFileNameA
Boolean corresponding to the decision to record the event based on the selection being met.
Definition: TrigAFPDijetComboHypoTool.h:38
DescendingEt
Definition: TrigEgammaTLAPhotonReAlgo.cxx:15
ComboHypoToolBase
Base class for tools which cut on properties of multi-object or multi-leg chains. User should derive ...
Definition: ComboHypoToolBase.h:26
TrigPassBits.h
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
TrigAFPDijetComboHypoTool::TrigAFPDijetComboHypoTool
TrigAFPDijetComboHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: TrigAFPDijetComboHypoTool.cxx:17
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
TrigAFPDijetComboHypoTool.h
TrigAFPDijetComboHypoTool::m_transportBeamC
ToolHandle< IAFPProtonTransportTool > m_transportBeamC
Proton transport parameterizaton object used in the proton position prediction for ATLAS C side.
Definition: TrigAFPDijetComboHypoTool.h:45
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
TrigAFPDijetComboHypoTool::m_beamEnergy
Gaudi::Property< float > m_beamEnergy
energy of one beam i.e. half of centre-of-mass energy
Definition: TrigAFPDijetComboHypoTool.h:54
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::ReadHandle::get
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Monitored::fill
void fill(const ToolHandle< GenericMonitoringTool > &tool, T &&... variables)
Definition: MonitoredGroup.h:128
TrigAFPDijetComboHypoTool::m_totalEnergy
float m_totalEnergy
beams centre-of-mass energy 2*m_beamEnergy
Definition: TrigAFPDijetComboHypoTool.h:55
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
DescendingEt::operator()
bool operator()(const xAOD::Photon *l, const xAOD::Photon *r) const
Definition: TrigEgammaTLAPhotonReAlgo.cxx:17
AFPTrack.h
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
JetContainer.h
TrigAFPDijetComboHypoTool::executeAlg
virtual bool executeAlg(const std::vector< Combo::LegDecision > &combination, const EventContext &ctx) const override
Only a dummy implementation exists in ComboHypoToolBase.
Definition: TrigAFPDijetComboHypoTool.cxx:79
TrigAFPDijetComboHypoTool::m_alignmentCorrection_nearA
Gaudi::Property< float > m_alignmentCorrection_nearA
Beam alignment corrections in the x position of ATLAS A side.
Definition: TrigAFPDijetComboHypoTool.h:63
TrigAFPDijetComboHypoTool::m_maxProtonDist
Gaudi::Property< float > m_maxProtonDist
Threshold for the radius distance between parameterization and measurements.
Definition: TrigAFPDijetComboHypoTool.h:48
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
Definition: PathResolver.cxx:183
TrigAFPDijetComboHypoTool::m_maxProtonDiff_y
Gaudi::Property< float > m_maxProtonDiff_y
Threshold for the y distance between parameterization and measurements.
Definition: TrigAFPDijetComboHypoTool.h:52
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
TrigAFPDijetComboHypoTool::m_alignmentCorrection_nearC
Gaudi::Property< float > m_alignmentCorrection_nearC
Beam alignment corrections in the x position of ATLAS C side.
Definition: TrigAFPDijetComboHypoTool.h:65
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
TrigAFPDijetComboHypoTool::m_protonTransportParamFileNameC
Gaudi::Property< std::string > m_protonTransportParamFileNameC
Definition: TrigAFPDijetComboHypoTool.h:40
TrigAFPDijetComboHypoTool::m_GeV
const float m_GeV
Variable to convert from MeV to GeV.
Definition: TrigAFPDijetComboHypoTool.h:68