ATLAS Offline Software
TrigAFPDijetComboHypoTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 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);
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);
65  ATH_MSG_DEBUG("Path to param file side A: "<<filePathA);
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) const {
80 
81  ATH_MSG_DEBUG("TrigAFPDijetComboHypoTool::executeAlg Executing algorithm");
82 
83  std::vector<ElementLink<xAOD::JetContainer>> selected_jets;
84 
85  // Expecting to run over chains with the signature HLT_afp_2jX, and hence to be supplied with three Decision Objects for each combination.
86  if(combination.size() != 3) ATH_MSG_ERROR("Number of leg decisions is not 3!");
87 
88  // One of these is the AFP Decision Object, which we ignore as we are fetching the AFP reconstruction directly from a ReadHandle.
89  // The other two should be Jet Decision Objects.
90  for(const auto& comb: combination){
91  const auto dec = comb.second;
92  const auto jet_link = TrigCompositeUtils::findLink<xAOD::JetContainer>(*dec, TrigCompositeUtils::featureString()).link;
93  if (jet_link.isValid()) {
94  selected_jets.push_back(jet_link);
95  }
96  }
97 
98  if(selected_jets.size() != 2){
99  ATH_MSG_ERROR("Expecting to combine exactly two jets, but instead found "
100  << selected_jets.size() << ". Will throw a runtime error");
101  throw std::runtime_error(
102  "Expecting to combine exactly two jets, but instead found " +
103  std::to_string(selected_jets.size()));
104  }
105 
106  // Get jet pair
107  auto jetLink1 = selected_jets[0]; // Need to check if jets are actually ordered in pT
108  auto jetLink2 = selected_jets[1];
109 
110  TLorentzVector jet1_vec = (*jetLink1)->p4();
111  TLorentzVector jet2_vec = (*jetLink2)->p4();
112  TLorentzVector dijet = jet1_vec + jet2_vec;
113 
114  // Calculate dijet quantities
115  auto dijetMass = Monitored::Scalar( "DijetMass" , -999.0 );
116  auto dijetRapidity = Monitored::Scalar( "DijetRapidity" , -999.0 );
117  dijetMass = dijet.M() * m_GeV;
118  ATH_MSG_DEBUG("AFP ComboHypo::DijetMass "<<dijetMass);
119  dijetRapidity = dijet.Rapidity();
120  Monitored::fill(m_monTool, dijetMass);
121  Monitored::fill(m_monTool, dijetRapidity);
122 
123  // Calculate relative energy loos
124  auto xiJet1 = Monitored::Scalar( "XiJet1" , -999.0 );
125  auto xiJet2 = Monitored::Scalar( "XiJet2" , -999.0 );
126  xiJet1 = exp(dijetRapidity) * dijetMass / m_totalEnergy;
127  xiJet2 = exp(-dijetRapidity) * dijetMass / m_totalEnergy;
128  Monitored::fill(m_monTool, xiJet1);
129  Monitored::fill(m_monTool, xiJet2);
130 
131  // Predict proton positions on AFP sides A and C
132  auto predictProtonAEnergy = Monitored::Scalar( "PredictProtonAEnergy" , -999.0 );
133  auto predictProtonCEnergy = Monitored::Scalar( "PredictProtonCEnergy" , -999.0 );
134  predictProtonAEnergy = m_beamEnergy * (1. - xiJet1); // Side A
135  predictProtonCEnergy = m_beamEnergy * (1. - xiJet2); // Side C
136  Monitored::fill(m_monTool, predictProtonAEnergy);
137  Monitored::fill(m_monTool, predictProtonCEnergy);
138 
139  // Side A position prediction
140  auto sideA_predictX = Monitored::Scalar( "SideA_predictX" , -999.0 );
141  auto sideA_predictY = Monitored::Scalar( "SideA_predictY" , -999.0 );
142  sideA_predictX = 1e3 * m_transportBeamA->x(0, 0, 0, 0, 0, predictProtonAEnergy) + m_protonPosShift_x;
143  sideA_predictY = 1e3 * m_transportBeamA->x(0, 0, 0, 0, 0, predictProtonAEnergy) + m_protonPosShift_y;
144  Monitored::fill(m_monTool, sideA_predictX);
145  Monitored::fill(m_monTool, sideA_predictY);
146 
147  // Side C position prediction
148  auto sideC_predictX = Monitored::Scalar( "SideC_predictX" , -999.0 );
149  auto sideC_predictY = Monitored::Scalar( "SideC_predictY" , -999.0 );
150  sideC_predictX = 1e3 * m_transportBeamC->x(0, 0, 0, 0, 0, predictProtonCEnergy) + m_protonPosShift_x;
151  sideC_predictY = 1e3 * m_transportBeamC->x(0, 0, 0, 0, 0, predictProtonCEnergy) + m_protonPosShift_y;
152  Monitored::fill(m_monTool, sideC_predictX);
153  Monitored::fill(m_monTool, sideC_predictY);
154 
155  // Retrieve AFP track container
157 
158  double sideA_minDist = 9e9;
159  double sideC_minDist = 9e9;
160 
161  int nearestTrackSideAId = 999;
162  int nearestTrackSideCId = 999;
163 
164  auto xDiff = Monitored::Scalar("XDiff",-999.0);
165  auto yDiff = Monitored::Scalar("YDiff",-999.0);
166  auto distance = Monitored::Scalar("distance",-999.0);
167 
168  // Find nearest track
169  for(auto track: (*tracksAFP)){
170 
171  xDiff = -999.0;
172  yDiff = -999.0;
173  distance = -999.0;
174 
175  // Side A
176  if(track->stationID() == 1){
177 
178  xDiff = sideA_predictX - (track->xLocal() + m_alignmentCorrection_nearA);
179  yDiff = sideA_predictY - track->yLocal();
180  distance = sqrt(xDiff * xDiff + yDiff * yDiff);
181 
182  if(distance < sideA_minDist){
183  sideA_minDist = distance;
184  nearestTrackSideAId = track->index();
185  }
186 
187  }else if(track->stationID() == 2){
188 
189  xDiff = sideC_predictX - (track->xLocal() + m_alignmentCorrection_nearC);
190  yDiff = sideC_predictY - track->yLocal();
191  distance = sqrt(xDiff * xDiff + yDiff * yDiff);
192 
193  if(distance < sideC_minDist){
194  sideC_minDist = distance;
195  nearestTrackSideCId = track->index();
196  }
197  }// End of if for choosing AFP station
198 
199  Monitored::fill(m_monTool, xDiff);
200  Monitored::fill(m_monTool, yDiff);
202 
203  }// End of loop over AFP track
204 
205  bool passRCutA = false;
206  bool passRCutC = false;
207 
208  bool passXYCutA = false;
209  bool passXYCutC = false;
210 
211  auto sideA_trackX = Monitored::Scalar("SideA_trackX",-999.0);
212  auto sideA_trackY = Monitored::Scalar("SideA_trackY",-999.0);
213  auto sideA_diffX = Monitored::Scalar("SideA_diffX",-999.0);
214  auto sideA_diffY = Monitored::Scalar("SideA_diffY",-999.0);
215 
216  auto sideC_trackX = Monitored::Scalar("SideC_trackX",-999.0);
217  auto sideC_trackY = Monitored::Scalar("SideC_trackY",-999.0);
218  auto sideC_diffX = Monitored::Scalar("SideC_diffX",-999.0);
219  auto sideC_diffY = Monitored::Scalar("SideC_diffY",-999.0);
220 
221  // Cuts on A side
222  if(nearestTrackSideAId != 999){
223 
224  sideA_trackX = tracksAFP.get()->at(nearestTrackSideAId)->xLocal() + m_alignmentCorrection_nearA;
225  sideA_trackY = tracksAFP.get()->at(nearestTrackSideAId)->yLocal();
226  sideA_diffX = sideA_predictX - sideA_trackX;
227  sideA_diffY = sideA_predictY - sideA_trackY;
228 
229  ATH_MSG_DEBUG("TrigAFPDijetComboHypoTool::execute sideA_diffX: " << sideA_diffX);
230 
231  if(sideA_minDist < m_maxProtonDist) passRCutA = true;
232 
233  if(fabs(sideA_diffX) < m_maxProtonDiff_x && fabs(sideA_diffY) < m_maxProtonDiff_y) passXYCutA = true;
234 
235  }else{
236  passRCutA = false;
237  passXYCutA = false;
238  }
239 
240  // Cuts on C side
241  if(nearestTrackSideCId != 999){
242 
243  sideC_trackX = tracksAFP.get()->at(nearestTrackSideCId)->xLocal() + m_alignmentCorrection_nearC;
244  sideC_trackY = tracksAFP.get()->at(nearestTrackSideCId)->yLocal();
245  sideC_diffX = sideC_predictX - sideC_trackX;
246  sideC_diffY = sideC_predictY - sideC_trackY;
247 
248  if(sideC_minDist < m_maxProtonDist) passRCutC = true;
249 
250  if(fabs(sideC_diffX) < m_maxProtonDiff_x && fabs(sideC_diffY) < m_maxProtonDiff_y) passXYCutC = true;
251 
252  }else{
253  passRCutC = false;
254  passXYCutC = false;
255  }
256 
257  Monitored::fill(m_monTool,sideA_trackX);
258  Monitored::fill(m_monTool,sideA_trackY);
259  Monitored::fill(m_monTool,sideA_diffX);
260  Monitored::fill(m_monTool,sideA_diffY);
261 
262  Monitored::fill(m_monTool,sideC_trackX);
263  Monitored::fill(m_monTool,sideC_trackY);
264  Monitored::fill(m_monTool,sideC_diffX);
265  Monitored::fill(m_monTool,sideC_diffY);
266 
267  bool pass = false;
268 
269  if(passRCutA && passRCutC && passXYCutA && passXYCutC) pass = true;
270 
271  return pass;
272 
273 }
TrigAFPDijetComboHypoTool::m_transportBeamA
ToolHandle< IAFPProtonTransportTool > m_transportBeamA
Definition: TrigAFPDijetComboHypoTool.h:43
TrigAFPDijetComboHypoTool::m_AFPtrackCollectionReadKey
SG::ReadHandleKey< xAOD::AFPTrackContainer > m_AFPtrackCollectionReadKey
Definition: TrigAFPDijetComboHypoTool.h:70
beamspotman.r
def r
Definition: beamspotman.py:676
AFPTrackContainer.h
Jet.h
PathResolver::RecursiveSearch
@ RecursiveSearch
Definition: PathResolver.h:28
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
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
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:70
TrigAFPDijetComboHypoTool::initialize
virtual StatusCode initialize() override
Definition: TrigAFPDijetComboHypoTool.cxx:30
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
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
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
TrigAFPDijetComboHypoTool::executeAlg
virtual bool executeAlg(const std::vector< Combo::LegDecision > &combination) const override
Only a dummy implementation exists in ComboHypoToolBase.
Definition: TrigAFPDijetComboHypoTool.cxx:79
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:122
TrigAFPDijetComboHypoTool::m_totalEnergy
float m_totalEnergy
beams centre-of-mass energy 2*m_beamEnergy
Definition: TrigAFPDijetComboHypoTool.h:55
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtilsRoot.cxx:884
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
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::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
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
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:512
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