Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
IParticleRetrievalTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Package includes
7 #include <ostream>
8 
9 // Anonymous namespace contains helper functions
10 namespace {
12  using CLIDTuple_t =
13  std::tuple<HLT::class_id_type, xAOD::Type::ObjectType, std::string>;
14 
15  template <std::size_t FROM, std::size_t TO>
16  bool CLIDLookUp(
19  {
20  static const std::vector<CLIDTuple_t> CLIDVector {
21  {1178459224, xAOD::Type::Muon, "xAOD::MuonContainer"},
22  {1087532415, xAOD::Type::Electron, "xAOD::ElectronContainer"},
23  {1219821989, xAOD::Type::CaloCluster, "xAOD::CaloClusterContainer"},
24  {1105575213, xAOD::Type::Photon, "xAOD::PhotonContainer"},
25  {1177172564, xAOD::Type::Tau, "xAOD::TauJetContainer"}
26  };
27  auto itr = std::find_if(CLIDVector.begin(), CLIDVector.end(),
28  [from] (const CLIDTuple_t& tup) {
29  return std::get<FROM>(tup) == from;
30  });
31  if (itr == CLIDVector.end() )
32  return false;
33  else {
34  to = std::get<TO>(*itr);
35  return true;
36  }
37  }
38  bool CLIDToObjectType(xAOD::Type::ObjectType& type, HLT::class_id_type clid)
39  {
40  return CLIDLookUp<0, 1>(type, clid);
41  }
42  bool ObjectTypeToCLID(HLT::class_id_type& clid, xAOD::Type::ObjectType type)
43  {
44  return CLIDLookUp<1, 0>(clid, type);
45  }
46  bool CLIDToContainerType(std::string& name, HLT::class_id_type clid)
47  {
48  return CLIDLookUp<0, 2>(name, clid);
49  }
50 
51 } //> end anonymous namespace
52 
53 namespace Trig {
55  asg::AsgTool(name)
56  {
57  declareProperty("TrigDecisionTool", m_tdt,
58  "The trigger decision tool to use.");
59  declareProperty("WarnOnNavigationError", m_warnOnNavigationFailure = true,
60  "Only spit a warning on a navigation error, don't cause a job failure.");
61 
62  }
63 
65 
67  {
68  ATH_MSG_INFO("Initializing " << name() );
69  ATH_CHECK( m_tdt.retrieve() );
70  return StatusCode::SUCCESS;
71  }
72 
74  std::vector<std::vector<const xAOD::IParticle*>>& combinations,
75  const std::string& chain,
76  bool rerun) const
77  {
78  // Make sure what we're getting is cleared.
79  combinations.clear();
80  // Start by getting the chain group
81  const ChainGroup* cg = m_tdt->getChainGroup(chain);
82  // Make sure that this group actually contains triggers. If it doesn't then
83  // this is very wrong and the job shouldn't be allowed to continue
84  if (cg->getListOfTriggers().size() == 0) {
85  ATH_MSG_ERROR("Chain group " << chain
86  << " is empty! This means that no matching chains were found!");
87  return StatusCode::FAILURE;
88  }
89  unsigned int condition = TrigDefs::Physics;
90  if (rerun)
91  condition |= TrigDefs::allowResurrectedDecision;
92  if (!cg->isPassed(condition) ) {
93  ATH_MSG_DEBUG("Chain: " << chain << " was not passed!");
94  return StatusCode::SUCCESS;
95  }
96 
97  FeatureContainer features = cg->features(condition);
98  for (const Combination& combo : features.getCombinations() ) {
99  // The assumption here is that each combination represents a *single* way
100  // in which the trigger could have been passed. This should be true for
101  // the types of trigger that this tool expects to examine. It won't be
102  // true for (e.g.) jet triggers.
103  std::vector<const xAOD::IParticle*> currentCombination;
104  bool navFailure = false;
105  for (const HLT::TriggerElement* te : combo.tes() ) {
106  if (!retrieveParticles(currentCombination, te, navFailure).isSuccess() ) {
107  // Interpret a failure this way so that we can report the chain name
108  ATH_MSG_ERROR("Failed to retrieve particles for chain " << chain );
109  return StatusCode::FAILURE;
110  }
111  // If the navigation failed for this combination ignore it completely
112  if (navFailure)
113  break;
114  }
115  if (navFailure)
116  ATH_MSG_WARNING("Skipping combination for chain " << chain
117  << " due to navigation failure");
118  else
119  combinations.push_back(currentCombination);
120  }
121  return StatusCode::SUCCESS;
122  }
123 
125  std::vector<const xAOD::IParticle*>& combination,
126  const HLT::TriggerElement* te,
127  bool& navFailure) const
128  {
129  ATH_MSG_DEBUG( "Processing TE " << Trig::getTEName(*te) );
130  // Keep track of whether or not we found a particle here.
131  const xAOD::IParticle* part = nullptr;
132  for (const auto& feature : te->getFeatureAccessHelpers() ) {
134  if (!CLIDToObjectType(type, feature.getCLID() ) )
135  // Skip any features that don't hold 'final' state particles
136  continue;
138  // If this is an egamma type we have to check if we are meant to be
139  // looking for a CaloCluster instead!
141  if (egType == xAOD::Type::Other) {
142  std::string message =
143  "Unable to determine the correct type for TE " + Trig::getTEName(*te);
144  navFailure = true;
147  return StatusCode::SUCCESS;
148  }
149  else {
151  return StatusCode::FAILURE;
152  }
153  }
154  else if (egType == xAOD::Type::CaloCluster) {
155  HLT::class_id_type clid = 0;
156  ObjectTypeToCLID(clid, egType);
157  // This will be where we store the TE containing the calo cluster
158  // feature
159  const HLT::TriggerElement* sourceTE = nullptr;
160  const HLT::TrigNavStructure* navigation =
161  m_tdt->ExperimentalAndExpertMethods().getNavigation();
163  navigation->getFeatureRecursively(te, clid, "", sourceTE);
164  if (!sourceTE) {
165  std::ostringstream os;
166  os << "Unable to retrieve feature of type " << egType
167  << " from TE " << Trig::getTEName(*te);
168  navFailure = true;
170  ATH_MSG_WARNING( os.str() );
171  return StatusCode::SUCCESS;
172  }
173  else {
174  ATH_MSG_ERROR( os.str() );
175  return StatusCode::FAILURE;
176  }
177  }
178  ATH_CHECK( retrieveFeatureParticle(part, egFeature, sourceTE, navFailure) );
179  if (navFailure)
180  return StatusCode::SUCCESS;
181  // If it's a calo-cluster like TE then stop here, otherwise we'll
182  // encounter the other EG type again and fail...
183  break;
184  }
185  else if (egType != type) {
186  // This is the wrong feature to be looking at
187  continue;
188  }
189  // Otherwise we continue as before
190  }
191  // If we found a particle from another feature access helper then this is
192  // a problem. Our assumption is that there is only one particle per leg!
193  if (part) {
194  std::string message = "TE" + Trig::getTEName(*te) + "has multiple " +
195  "'final' particles attached to it! This breaks this tool's asumptions!";
196  navFailure = true;
199  return StatusCode::SUCCESS;
200  }
201  else {
203  return StatusCode::FAILURE;
204  }
205  }
206  ATH_CHECK( retrieveFeatureParticle(part, feature, te, navFailure) );
207  if (navFailure)
208  return StatusCode::SUCCESS;
209  } //> end loop over features
210 
211  // If we found a particle then we can stop going through this branch of the
212  // tree
213  if (part) {
214  combination.push_back(part);
215  return StatusCode::SUCCESS;
216  }
217 
218  // Otherwise look at each of the next TEs separately
219  for (const HLT::TriggerElement* nextTE :
221  ATH_CHECK( retrieveParticles(combination, nextTE, navFailure) );
222 
223  return StatusCode::SUCCESS;
224  }
225 
227  const HLT::TriggerElement* te) const
228  {
229  // We need to check the TE name for this
230  std::string teName = Trig::getTEName(*te);
231  if (teName.find("etcut") != std::string::npos &&
232  teName.find("trkcut") == std::string::npos)
234  else if (teName.starts_with( "EF_e"))
235  return xAOD::Type::Electron;
236  else if (teName.starts_with( "EF_g"))
237  return xAOD::Type::Photon;
238  else
239  return xAOD::Type::Other;
240  }
241 
243  const xAOD::IParticle*& particle,
245  const HLT::TriggerElement* te,
246  bool& navFailure) const
247  {
248  // Get the right container type name
249  std::string containerType;
250  if (!CLIDToContainerType(containerType, feature.getCLID() ) ) {
251  ATH_MSG_ERROR("Unrecognised CLID " << feature.getCLID() << " received!");
252  // This isn't a navigation error - this is a failure in the tool's
253  // internal logic!
254  return StatusCode::FAILURE;
255  }
256  // Build a vector of typeless features so that we can use the central
257  // functions.
258  const HLT::TrigNavStructure* navigation =
259  m_tdt->ExperimentalAndExpertMethods().getNavigation();
260 
261 
263  auto typelessHolder = navigation->getHolder(feature);
264 
265  if (!typelessHolder) {
266  std::string message = "Typeless holder for feature not present!";
267  navFailure = true;
270  return StatusCode::SUCCESS;
271  }
272  else {
274  return StatusCode::FAILURE;
275  }
276  }
277  const xAOD::IParticleContainer* cont(nullptr);
278  // Get the name used in the event store
279  std::string key = HLTNavDetails::formatSGkey(
280  "HLT", containerType, typelessHolder->label() );
281  // Now things are *much* more familiar
282  if (!evtStore()->contains<xAOD::IParticleContainer>(key) ) {
283  std::string message = "Store does not contain " + key + "!";
284  navFailure = true;
287  return StatusCode::SUCCESS;
288  }
289  else {
291  return StatusCode::FAILURE;
292  }
293  }
294  ATH_CHECK( evtStore()->retrieve(cont, key) );
296  if (cont->size() < idx.objectsEnd() ) {
297  std::ostringstream os;
298  os << "Featured object end " << idx.objectsEnd()
299  << " is *after* the end of container " << key;
300  navFailure = true;
302  ATH_MSG_WARNING( os.str() );
303  return StatusCode::SUCCESS;
304  }
305  else {
306  ATH_MSG_ERROR( os.str() );
307  return StatusCode::FAILURE;
308  }
309  }
310  std::vector<const xAOD::IParticle*> particleFeatures;
311  particleFeatures.reserve(idx.objectsEnd() - idx.objectsBegin() );
312  auto begin = cont->begin();
313  auto end = cont->begin();
314  std::advance(begin, idx.objectsBegin() );
315  std::advance(end, idx.objectsEnd() );
316  particleFeatures.insert(particleFeatures.end(), begin, end);
317 
318  // Make sure the answer is what we expect
319  std::ostringstream os;
320  switch (particleFeatures.size() ) {
321  case 0:
322  os << "No particles retrieved from feature "
323  << navigation->label(feature.getCLID(), feature.getIndex().subTypeIndex() )
324  << " from TE " << Trig::getTEName(*te);
325  navFailure = true;
327  ATH_MSG_WARNING(os.str() );
328  return StatusCode::SUCCESS;
329  }
330  else {
331  ATH_MSG_ERROR(os.str() );
332  return StatusCode::FAILURE;
333  }
334  case 1:
335  // Set the output.
336  particle = particleFeatures.at(0);
337  break;
338  default:
339  // Some TEs can end up reporting multiple outputs within the same RoI.
340  // AFAIK this only happens within EGamma TEs but I don't know that for
341  // sure. In any case this shouldn't matter too much for the matching
342  // given that they will be nearby each other. Just return the highest pT
343  // object.
344  particle = *(std::max_element(
345  particleFeatures.begin(), particleFeatures.end(),
346  [] (const xAOD::IParticle* lhs, const xAOD::IParticle* rhs)
347  { return lhs->pt() < rhs->pt(); }) );
348  }
349  return StatusCode::SUCCESS;
350  }
351 
352 } //> end namespace Trig
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
Trig::IParticleRetrievalTool::getEGammaTEType
xAOD::Type::ObjectType getEGammaTEType(const HLT::TriggerElement *te) const
Get the type of particle that should be retrieved from this TE.
Definition: IParticleRetrievalTool.cxx:226
HLT::TriggerElement::ObjectIndex
Helper class for conversion from/to int stored in TE and pair of ints used in Navigation Object point...
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:75
Trig::getTEName
std::string getTEName(const HLT::TriggerElement &te)
converts TEid to TE name (this may not always work, it depends on the availability of config)
Definition: TDTUtilities.cxx:61
Trig::IParticleRetrievalTool::m_tdt
ToolHandle< Trig::TrigDecisionTool > m_tdt
The TrigDecisionTool that will be used to get the navigation.
Definition: IParticleRetrievalTool.h:88
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
Trig::IParticleRetrievalTool::m_warnOnNavigationFailure
bool m_warnOnNavigationFailure
Be forgiving about the navigation not matching our expectations.
Definition: IParticleRetrievalTool.h:91
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
IParticleRetrievalTool.h
HLT::TrigNavStructure::label
std::string label(class_id_type clid, const index_or_label_type &sti_or_label) const
Definition: TrigNavStructure.cxx:775
Trig
The common trigger namespace for trigger analysis tools.
Definition: LArCellMonAlg.h:33
ObjectType
ObjectType
Definition: BaseObject.h:11
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
asg
Definition: DataHandleTestTool.h:28
HLT::TriggerElement::FeatureAccessHelper::getCLID
class_id_type getCLID() const
Class ID of object.
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:208
navigation2dot.teName
def teName(teid)
Definition: navigation2dot.py:59
LArG4GenerateShowerLib.condition
condition
Definition: LArG4GenerateShowerLib.py:19
Trig::IParticleRetrievalTool::IParticleRetrievalTool
IParticleRetrievalTool(const std::string &name)
Standard constructor.
Definition: IParticleRetrievalTool.cxx:54
HLTNavDetails::formatSGkey
std::string formatSGkey(const std::string &prefix, const std::string &containername, const std::string &label)
declaration of formatting function.
Definition: Holder.cxx:122
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
HLT::TrigNavStructure
Definition: TrigNavStructure.h:40
ReweightUtils.message
message
Definition: ReweightUtils.py:15
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
xAOD::CaloCluster
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloCluster.h:19
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
Trig::ChainGroup::features
const FeatureContainer features(unsigned int condition=TrigDefs::Physics) const
returns all features related to given chain group of HLT chains or L1 items Note: This does not yet w...
Definition: ChainGroup.cxx:726
Trig::IParticleRetrievalTool::~IParticleRetrievalTool
~IParticleRetrievalTool() override
Default destructor.
Definition: IParticleRetrievalTool.cxx:64
Trig::FeatureContainer
Definition: FeatureContainer.h:54
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
HLT::TriggerElement::ObjectIndex::subTypeIndex
sub_index_type subTypeIndex() const
to get collection index
Definition: TrigNavStructure/Root/TriggerElement.cxx:247
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
HLT::TrigNavStructure::getDirectPredecessors
static const std::vector< TriggerElement * > & getDirectPredecessors(const TriggerElement *te)
returns list of direct predecessors (nodes seeding me)
Definition: TrigNavStructure.cxx:120
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Trig::Combination
Definition: Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/Combination.h:55
HLT::TriggerElement
TriggerElement is the basic ingreedient of the interface between HLT algorithms and the navigation It...
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:27
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
HLT::class_id_type
uint32_t class_id_type
Definition: Trigger/TrigEvent/TrigNavStructure/Root/Types.h:11
Trig::IParticleRetrievalTool::retrieveFeatureParticle
StatusCode retrieveFeatureParticle(const xAOD::IParticle *&particle, const HLT::TriggerElement::FeatureAccessHelper &feature, const HLT::TriggerElement *te, bool &navFailure) const
Retrieve an IParticle from a feature.
Definition: IParticleRetrievalTool.cxx:242
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
Trig::ChainGroup
Definition: ChainGroup.h:51
Trig::ChainGroup::isPassed
bool isPassed(unsigned int condition=TrigDefs::Physics) const
tells if chain group passed
Definition: ChainGroup.cxx:208
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
CxxUtils::to
CONT to(RANGE &&r)
Definition: ranges.h:39
HLT::TrigNavStructure::getFeatureRecursively
TriggerElement::FeatureAccessHelper getFeatureRecursively(const TriggerElement *startTE, class_id_type clid, const index_or_label_type &index_or_label, const TriggerElement *&sourceTE) const
recursive search for features the function is similar to the above butif th features is not found at ...
Definition: TrigNavStructure.cxx:797
xAOD::Photon
Photon_v1 Photon
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Photon.h:17
python.combo.combinations
def combinations(items, n)
Definition: combo.py:85
Muon
struct TBPatternUnitContext Muon
HLT::TriggerElement::FeatureAccessHelper::getIndex
const ObjectIndex & getIndex() const
index in the external ojects array
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:209
HLT::TriggerElement::FeatureAccessHelper
the FeatureAccessHelper is a class used to keep track of features attached to this TE.
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:192
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
xAODType::Tau
@ Tau
The object is a tau (jet)
Definition: ObjectType.h:49
HLT::TriggerElement::getFeatureAccessHelpers
const std::vector< FeatureAccessHelper > & getFeatureAccessHelpers() const
returns all features which ara attached to this TE
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:238
Trig::FeatureContainer::getCombinations
const std::vector< Trig::Combination > & getCombinations() const
gives back reference to combinations collected through append
Definition: FeatureContainer.h:135
Trig::ChainGroup::getListOfTriggers
std::vector< std::string > getListOfTriggers() const
Definition: ChainGroup.cxx:467
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Trig::IParticleRetrievalTool::retrieveParticles
StatusCode retrieveParticles(std::vector< std::vector< const xAOD::IParticle * >> &combinations, const std::string &chain, bool rerun=false) const override
Retrieve the particles that caused this trigger to fire.
Definition: IParticleRetrievalTool.cxx:73
Trig::IParticleRetrievalTool::initialize
StatusCode initialize() override
Initialise the tool.
Definition: IParticleRetrievalTool.cxx:66
HLT::TrigNavStructure::getHolder
const BaseHolder * getHolder(const TriggerElement::FeatureAccessHelper &fea) const
Definition: TrigNavStructure.cxx:923
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37