ATLAS Offline Software
Loading...
Searching...
No Matches
xAODJetRetriever.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
11#include "xAODPFlow/PFO.h"
13
14#include "AthenaKernel/Units.h"
15using Athena::Units::GeV;
16
17namespace JiveXML {
18
25 xAODJetRetriever::xAODJetRetriever(const std::string& type,const std::string& name,const IInterface* parent):
26 AthAlgTool(type,name,parent){}
27
29 ATH_CHECK(m_keys.initialize());
30 if (m_bTaggerNames.size()!=m_CDIPaths.size()){
31 ATH_MSG_WARNING("Number of btaggers and CDI files do not match. Will not retrieve b-tagging information.");
32 return StatusCode::SUCCESS;
33 } else {
35 }
36 for (unsigned int i=0; i<m_nTaggers; i++){
37 std::string taggerName = m_bTaggerNames[i];
39 btagSelTool.setTypeAndName("BTaggingSelectionTool/btagSelTool_"+taggerName);
40 ATH_CHECK(btagSelTool.setProperty("TaggerName", taggerName));
41 ATH_CHECK(btagSelTool.setProperty("JetAuthor", "AntiKt4EMPFlowJets")); // only AntiKt4EMPFlowJets is supported
42 ATH_CHECK(btagSelTool.setProperty("OperatingPoint", "FixedCutBEff_70")); // the working point doesn't matter because we don't cut on the tagger discriminant, but it must exist in CDI.
43 ATH_CHECK(btagSelTool.setProperty("FlvTagCutDefinitionsFileName", m_CDIPaths[i]));
44 ATH_CHECK(btagSelTool.setProperty( "MinPt", 0.0));
45 ATH_CHECK(btagSelTool.initialize());
46 m_btagSelTools.emplace(taggerName, btagSelTool);
47 }
48
49 return StatusCode::SUCCESS;
50 }
51
52
57 StatusCode xAODJetRetriever::retrieve(ToolHandle<IFormatTool> &FormatTool) {
58
59 ATH_MSG_DEBUG( "in retrieve()" );
60
61 // Loop through the keys and retrieve the corresponding data
62 for (const auto& key : m_keys) {
64 if (cont.isValid()) {
65 DataMap data = getData(&(*cont), key.key());
66 if (FormatTool->AddToEvent(dataTypeName(), key.key() + "_xAOD", &data).isFailure()) {
67 ATH_MSG_WARNING("Failed to add collection " << key.key());
68 } else {
69 ATH_MSG_DEBUG(" (" << key.key() << ") retrieved");
70 }
71 } else {
72 ATH_MSG_WARNING("Collection " << key.key() << " not found in SG");
73 }
74 }
75
76 return StatusCode::SUCCESS;
77 }
78
79
84 const DataMap xAODJetRetriever::getData(const xAOD::JetContainer* jetCont, const std::string &jetkey) {
85
86 ATH_MSG_DEBUG( "in getData()" );
87
89
90 DataVect et; et.reserve(jetCont->size());
91 DataVect phi; phi.reserve(jetCont->size());
92 DataVect eta; eta.reserve(jetCont->size());
93 DataVect mass; mass.reserve(jetCont->size());
94 DataVect energy; energy.reserve(jetCont->size());
95 DataVect bTagName; bTagName.reserve(jetCont->size());
96 DataVect bTagValue; bTagValue.reserve(jetCont->size());
97 DataVect charge; energy.reserve(jetCont->size());
98 DataVect idVec; idVec.reserve(jetCont->size());
99 DataVect px; px.reserve(jetCont->size());
100 DataVect py; py.reserve(jetCont->size());
101 DataVect pz; pz.reserve(jetCont->size());
102 DataVect jvf; jvf.reserve(jetCont->size());
103 DataVect jvt; jvt.reserve(jetCont->size());
104 DataVect emfrac; emfrac.reserve(jetCont->size());
105
106 DataVect trackKey; trackKey.reserve(jetCont->size());
107 DataVect trackContKey; trackContKey.reserve(jetCont->size());
108 DataVect trackLinkCount; trackLinkCount.reserve(jetCont->size());
109 DataVect clusterID; clusterID.reserve(jetCont->size());
110
111 DataVect cellID; cellID.reserve(jetCont->size());
112 DataVect numCells; numCells.reserve(jetCont->size());
113
114 int id = 0;
115
116 int counter = 0;
117 for (const auto jet : *jetCont) {
118 if(!jet)continue;
119 ATH_MSG_DEBUG( " Jet #" << counter++ << " : eta = " << jet->eta() << ", phi = " << jet->phi() << ", pt = " << jet->pt() );
120
121 /* retrieve associated tracks and calo clusters */
122 size_t numConstit = jet->numConstituents();
123 std::vector<std::string> tempCellID;
124 size_t trackcounter = 0;
125 //TODO FIXME jet->rawConstituent(0) fails for some keys, including (but not exclusively) HLT_AntiKt10EMPFlowCSSKJets_nojcalib_ftf, HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf, HLT_AntiKt4EMPFlowJets_nojcalib_ftf, HLT_AntiKt4EMPFlowJets_subjesgscIS_ftf, HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf
126 if (numConstit > 0){
127 const xAOD::IParticle* constituent = jet->rawConstituent(0);
128 if (constituent){
129 xAOD::Type::ObjectType ctype=jet->rawConstituent(0)->type();
130 // PFlow and Flow jets from athena/Reconstruction/Jet/JetMomentTools/Root/JetTrackMomentsTool.cxx
131 if (ctype == xAOD::Type::ParticleFlow) {
132 // This jet is either a PFlow jet (constituent type: xAOD::FlowElement::PFlow) or UFO jets
133 for (size_t i = 0; i < numConstit; i++) {
134 const xAOD::PFO *constit =
135 dynamic_cast<const xAOD::PFO *>(jet->rawConstituent(i));
136 if (constit->isCharged()) {
137 const xAOD::TrackParticle *thisTrack = constit->track(0); // by construction xAOD::PFO can only have one track, in eflowRec usage
138 trackKey.emplace_back(DataType(thisTrack->index()));
139 trackContKey.emplace_back(m_tracksName.value());
140 trackcounter++;
141 } // We have a charged PFO
142 } // Loop on jet constituents
143 } else if (ctype == xAOD::Type::FlowElement) {
144 // This jet is made from xAOD::FlowElement, so we calculate the pflow moments if they're PFOs
145 size_t numConstit = jet->numConstituents();
146 for (size_t i = 0; i < numConstit; i++) {
147 const xAOD::FlowElement *constit = dynamic_cast<const xAOD::FlowElement *>(jet->rawConstituent(i));
148 // UFO jet constituents have signalType xAOD::FlowElement::Charged or xAOD::FlowElement::Neutral
149 // PFlow jet constituents have signalType xAOD::FlowElement::ChargedPFlow or xAOD::FlowElement::NeutralPFlow
150 if (constit != nullptr && ((constit->signalType() & xAOD::FlowElement::PFlow) || constit->signalType() == xAOD::FlowElement::Charged)) {
151 if (constit->isCharged()) {
152 const xAOD::TrackParticle *thisTrack = dynamic_cast<const xAOD::TrackParticle *>( constit->chargedObject( 0)); // PFO should have only 1 track
153 if (thisTrack != nullptr) {
154 trackKey.emplace_back(DataType(thisTrack->index()));
155 trackContKey.emplace_back(m_tracksName.value());
156 trackcounter++;
157 }
158 else
159 ATH_MSG_WARNING( "Charged PFO had no associated TrackParticle");
160 } // We have a charged PFO
161 } // The FlowElement is a PFO
162 } // Loop on jet constituents
163 } else if (ctype == xAOD::Type::CaloCluster) {
164 // get associated cluster
165 for (size_t j = 0; j < numConstit; ++j) {
166 const xAOD::CaloCluster *cluster = dynamic_cast<const xAOD::CaloCluster *>(jet->rawConstituent(j));
167 clusterID.emplace_back(DataType(cluster->index()));
168 if(!cluster->getCellLinks())continue;
169 for (const auto cc : *(cluster->getCellLinks())) {
170 if (std::find(tempCellID.begin(), tempCellID.end(), std::to_string( cc->caloDDE()->identify().get_compact())) != tempCellID.end()) {
171 continue;
172 } else {
173 cellID.emplace_back( DataType(cc->caloDDE()->identify().get_compact()));
174 tempCellID.emplace_back( std::to_string(cc->caloDDE()->identify().get_compact()));
175 }
176 }
177 ATH_MSG_VERBOSE(" Associated cluster: eta = " << cluster->eta() << ", phi = " << cluster->phi());
178 }
179 // get ghost associated tracks
180 std::vector<const xAOD::TrackParticle*> ghosttracks;
181 jet->getAssociatedObjects<xAOD::TrackParticle>(xAOD::JetAttribute::GhostTrack, ghosttracks);
182 if (ghosttracks.empty()) {
183 ATH_MSG_VERBOSE(" Associated track: ERROR");
184 } else {
185 for (size_t i = 0; i < ghosttracks.size(); i++) {
186
187 // can access the base track class, should be able to get tracker hits ?
188 // const Trk::Track* baseTrack = dynamic_cast< const Trk::Track* >( ghosttracks[i]->track());
189
190 trackKey.emplace_back(DataType(ghosttracks[i]->index()));
191 trackContKey.emplace_back(m_tracksName.value());
192
193 ATH_MSG_VERBOSE(" Associated track: d0 = " << ghosttracks[i]->d0() << ", pt = " << ghosttracks[i]->pt());
194 }
195 trackcounter = ghosttracks.size();
196 }
197 } else if (ctype == xAOD::Type::TrackParticle) {
198 for (size_t j = 0; j < numConstit; ++j) {
199 const xAOD::TrackParticle *track =
200 dynamic_cast<const xAOD::TrackParticle *>(jet->rawConstituent(j));
201 if (!track) {
202 ATH_MSG_VERBOSE(" Associated track: ERROR");
203 } else {
204 trackKey.emplace_back(DataType(track->index()));
205 trackContKey.emplace_back(m_tracksName.value());
206 trackcounter++;
207 ATH_MSG_VERBOSE(" Associated track: d0 = " << track->d0() << ", pt = " << track->pt());
208 }
209 }
210 }
211 }
212 }
213 trackLinkCount.emplace_back(DataType(trackcounter));
214 numCells.emplace_back(DataType(tempCellID.size()));
215
216
217 phi.emplace_back(DataType(jet->phi()));
218 eta.emplace_back(DataType(jet->eta()));
219 et.emplace_back(DataType(jet->pt()/GeV)); // hack ! no et in xAOD_Jet_v1 currently
220 idVec.emplace_back( DataType( ++id ));
221
222 mass.emplace_back(DataType(jet->m()/GeV));
223 energy.emplace_back( DataType(jet->e()/GeV ) );
224
225 px.emplace_back(DataType(jet->px()/GeV));
226 py.emplace_back(DataType(jet->py()/GeV));
227 pz.emplace_back(DataType(jet->pz()/GeV));
228
229 // bjet tagger values
230 if (jetkey!="AntiKt4EMPFlowJets" || (m_nTaggers==0)){
231 for (auto taggerName : m_bTaggerNames) {
232 bTagName.emplace_back(DataType("None"));
233 bTagValue.emplace_back(DataType(0.));
234 }
235 }else{
236 double btagValue;
237 for (auto taggerName : m_bTaggerNames) {
238 CP::CorrectionCode code = m_btagSelTools[taggerName]->getTaggerWeight(*jet, btagValue);
239 if (code != CP::CorrectionCode::Ok) {
240 ATH_MSG_DEBUG("Failed to get btagging weight for tagger " << taggerName);
241 btagValue = 0;
242 }
243 bTagName.emplace_back(DataType(taggerName));
244 bTagValue.emplace_back(DataType(btagValue));
245 }
246 }
247
248 float chargeread;
249 if (!jet->getAttribute<float>(xAOD::JetAttribute::Charge, chargeread)) {
250 ATH_MSG_DEBUG("Jet charge unavailable!");
251 charge.emplace_back( DataType( 0. ));
252 }else{
253 charge.emplace_back( DataType( chargeread ));
254 }
255
256 // updated for data15
257 // from: Reconstruction/MET/METReconstruction/Root/METJetFilterTool.cxx
258 std::vector<float> jvfread;
259 if(!jet->getAttribute<std::vector<float> >(xAOD::JetAttribute::JVF,jvfread)) {
260 ATH_MSG_DEBUG("Jet JVF unavailable!");
261 jvf.emplace_back( DataType( 1. ));
262 }else{
263 jvf.emplace_back( DataType( jvfread[0] ));
264 }
265
266 float jvtread;
267 if(!jet->getAttribute<float>(xAOD::JetAttribute::Jvt,jvtread)) {
268 ATH_MSG_DEBUG("Jet JVT unavailable!");
269 jvt.emplace_back(DataType(0.));
270 } else {
271 jvt.emplace_back(DataType(jvtread));
272 }
273
274 float emfracread = 0;
275 if(!jet->getAttribute(xAOD::JetAttribute::EMFrac,emfracread)) {
276 ATH_MSG_DEBUG("Jet EMFrac unavailable!");
277 emfrac.emplace_back( DataType( 0. ));
278 }else{
279 emfrac.emplace_back( DataType( emfracread ));
280 }
281
282 } // end loop
283
284 // four-vectors
285 DataMap["phi"] = phi;
286 DataMap["eta"] = eta;
287 DataMap["et"] = et;
288 DataMap["energy"] = energy;
289 DataMap["mass"] = mass;
290 std::string str_nTaggers = m_nTaggers>0 ? std::to_string(m_nTaggers) : "1"; // default to 1 if no btaggers so that atlantis can process the jets properly
291 DataMap["bTagName multiple=\""+str_nTaggers+"\""] = bTagName; // assigned by hand !
292 DataMap["bTagValue multiple=\""+str_nTaggers+"\""] = bTagValue;
293 DataMap["charge"] = charge;
294 DataMap["id"] = idVec;
295 DataMap["px"] = px;
296 DataMap["py"] = py;
297 DataMap["pz"] = pz;
298 DataMap["jvf"] = jvf;
299 DataMap["jvt"] = jvt;
300 DataMap["emfrac"] = emfrac;
301
302 if ((trackKey.size()) != 0){
303 double NTracksPerVertex = trackKey.size()*1./jetCont->size();
304 std::string tag = "trackIndex multiple=\"" +DataType(NTracksPerVertex).toString()+"\"";
305 DataMap[tag] = trackKey;
306 tag = "trackKey multiple=\"" +DataType(NTracksPerVertex).toString()+"\"";
307 DataMap[tag] = trackContKey;
308 }
309
310 if ((clusterID.size())!=0){
311 std::string tag = "clusterIndex multiple=\"" + DataType(clusterID.size()).toString()+"\"";
312 double NCellsPerJet = cellID.size()*1./jetCont->size();
313 tag = "cells multiple=\"" +DataType(NCellsPerJet).toString()+"\"";
314 DataMap[tag]=cellID;
315 }
316
317 DataMap["trackLinkCount"] = trackLinkCount;
318 DataMap["numCells"] = numCells;
319
320 ATH_MSG_DEBUG( dataTypeName() << " retrieved with " << phi.size() << " entries" );
321
322 return DataMap;
323 }
324
325
326} // JiveXML namespace
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Defines enum to access jet attribute and associated particles/objects.
Wrapper to avoid constant divisions when using units.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Return value from object correction CP tools.
@ Ok
The correction was done successfully.
size_type size() const noexcept
Returns the number of elements in the collection.
virtual std::string dataTypeName() const
Return the name of the data type that is generated by this retriever.
Gaudi::Property< std::vector< std::string > > m_bTaggerNames
SG::ReadHandleKeyArray< xAOD::JetContainer > m_keys
Gaudi::Property< std::vector< std::string > > m_CDIPaths
std::unordered_map< std::string, asg::AnaToolHandle< IBTaggingSelectionTool > > m_btagSelTools
virtual StatusCode initialize()
const DataMap getData(const xAOD::JetContainer *, const std::string &jetkey)
Puts the variables into a DataMap.
virtual StatusCode retrieve(ToolHandle< IFormatTool > &FormatTool)
For each jet collections retrieve basic parameters.
xAODJetRetriever(const std::string &type, const std::string &name, const IInterface *parent)
Standard Constructor.
Gaudi::Property< std::string > m_tracksName
size_t index() const
Return the index of this element within its container.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
a modified tool handle that allows its owner to configure new tools from the C++ side
StatusCode setProperty(const std::string &property, const T2 &value)
set the given property of the tool.
StatusCode initialize()
initialize the tool
void setTypeAndName(const std::string &val_typeAndName)
set the value of type and name
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
signal_t signalType() const
const xAOD::IParticle * chargedObject(std::size_t i) const
Class providing the definition of the 4-vector interface.
bool isCharged() const
is a charged PFO
Definition PFO_v1.cxx:251
const TrackParticle * track(unsigned int index) const
Retrieve a const pointer to a Rec::TrackParticle.
Definition PFO_v1.cxx:691
This header is shared inbetween the C-style server thread and the C++ Athena ServerSvc.
std::map< std::string, DataVect > DataMap
Definition DataType.h:59
std::vector< DataType > DataVect
Defines a map with a key and a vector of DataType objects e.g.
Definition DataType.h:58
Definition index.py:1
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32
@ TrackParticle
The object is a charged track particle.
Definition ObjectType.h:43
@ ParticleFlow
The object is a particle-flow object.
Definition ObjectType.h:41
@ FlowElement
The object is a track-calo-cluster.
Definition ObjectType.h:52
@ CaloCluster
The object is a calorimeter cluster.
Definition ObjectType.h:39
PFO_v1 PFO
Definition of the current "pfo version".
Definition PFO.h:17
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
TrackParticle_v1 TrackParticle
Reference the current persistent version:
JetContainer_v1 JetContainer
Definition of the current "jet container version".
Extra patterns decribing particle interation process.