ATLAS Offline Software
Loading...
Searching...
No Matches
xAODJetRetriever.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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 const std::string taggerKey{"TaggerName"};
37 const std::string authorKey{"JetAuthor"};
38 const std::string authorVal{"AntiKt4EMPFlowJets"};
39 const std::string opKey{"OperatingPoint"};
40 const std::string opVal{"FixedCutBEff_70"};
41 const std::string fnameKey{"FlvTagCutDefinitionsFileName"};
42 const std::string minPtKey{"MinPt"};
43 for (unsigned int i=0; i<m_nTaggers; i++){
44 std::string taggerName = m_bTaggerNames[i];
46 btagSelTool.setTypeAndName("BTaggingSelectionTool/btagSelTool_"+taggerName);
47 ATH_CHECK(btagSelTool.setProperty(taggerKey, taggerName));
48 ATH_CHECK(btagSelTool.setProperty(authorKey, authorVal)); // only AntiKt4EMPFlowJets is supported
49 ATH_CHECK(btagSelTool.setProperty(opKey, opVal)); // the working point doesn't matter because we don't cut on the tagger discriminant, but it must exist in CDI.
50 ATH_CHECK(btagSelTool.setProperty(fnameKey, m_CDIPaths[i]));
51 ATH_CHECK(btagSelTool.setProperty( minPtKey, 0.0));
52 ATH_CHECK(btagSelTool.initialize());
53 m_btagSelTools.emplace(taggerName, btagSelTool);
54 }
55
56 return StatusCode::SUCCESS;
57 }
58
59
64 StatusCode xAODJetRetriever::retrieve(ToolHandle<IFormatTool> &FormatTool) {
65
66 ATH_MSG_DEBUG( "in retrieve()" );
67
68 // Loop through the keys and retrieve the corresponding data
69 for (const auto& key : m_keys) {
71 if (cont.isValid()) {
72 DataMap data = getData(&(*cont), key.key());
73 if (FormatTool->AddToEvent(dataTypeName(), key.key() + "_xAOD", &data).isFailure()) {
74 ATH_MSG_WARNING("Failed to add collection " << key.key());
75 } else {
76 ATH_MSG_DEBUG(" (" << key.key() << ") retrieved");
77 }
78 } else {
79 ATH_MSG_WARNING("Collection " << key.key() << " not found in SG");
80 }
81 }
82
83 return StatusCode::SUCCESS;
84 }
85
86
91 const DataMap xAODJetRetriever::getData(const xAOD::JetContainer* jetCont, const std::string &jetkey) {
92
93 ATH_MSG_DEBUG( "in getData()" );
94
96
97 DataVect et; et.reserve(jetCont->size());
98 DataVect phi; phi.reserve(jetCont->size());
99 DataVect eta; eta.reserve(jetCont->size());
100 DataVect mass; mass.reserve(jetCont->size());
101 DataVect energy; energy.reserve(jetCont->size());
102 DataVect bTagName; bTagName.reserve(jetCont->size());
103 DataVect bTagValue; bTagValue.reserve(jetCont->size());
104 DataVect charge; energy.reserve(jetCont->size());
105 DataVect idVec; idVec.reserve(jetCont->size());
106 DataVect px; px.reserve(jetCont->size());
107 DataVect py; py.reserve(jetCont->size());
108 DataVect pz; pz.reserve(jetCont->size());
109 DataVect jvf; jvf.reserve(jetCont->size());
110 DataVect jvt; jvt.reserve(jetCont->size());
111 DataVect emfrac; emfrac.reserve(jetCont->size());
112
113 DataVect trackKey; trackKey.reserve(jetCont->size());
114 DataVect trackContKey; trackContKey.reserve(jetCont->size());
115 DataVect trackLinkCount; trackLinkCount.reserve(jetCont->size());
116 DataVect clusterID; clusterID.reserve(jetCont->size());
117
118 DataVect cellID; cellID.reserve(jetCont->size());
119 DataVect numCells; numCells.reserve(jetCont->size());
120
121 int id = 0;
122
123 int counter = 0;
124 for (const auto jet : *jetCont) {
125 if(!jet)continue;
126 ATH_MSG_DEBUG( " Jet #" << counter++ << " : eta = " << jet->eta() << ", phi = " << jet->phi() << ", pt = " << jet->pt() );
127
128 /* retrieve associated tracks and calo clusters */
129 size_t numConstit = jet->numConstituents();
130 std::vector<std::string> tempCellID;
131 size_t trackcounter = 0;
132 //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
133 if (numConstit > 0){
134 const xAOD::IParticle* constituent = jet->rawConstituent(0);
135 if (constituent){
136 xAOD::Type::ObjectType ctype=jet->rawConstituent(0)->type();
137 // PFlow and Flow jets from athena/Reconstruction/Jet/JetMomentTools/Root/JetTrackMomentsTool.cxx
138 if (ctype == xAOD::Type::ParticleFlow) {
139 // This jet is either a PFlow jet (constituent type: xAOD::FlowElement::PFlow) or UFO jets
140 for (size_t i = 0; i < numConstit; i++) {
141 const xAOD::PFO *constit =
142 static_cast<const xAOD::PFO *>(jet->rawConstituent(i));
143 if (constit->isCharged()) {
144 const xAOD::TrackParticle *thisTrack = constit->track(0); // by construction xAOD::PFO can only have one track, in eflowRec usage
145 trackKey.emplace_back(DataType(thisTrack->index()));
146 trackContKey.emplace_back(m_tracksName.value());
147 trackcounter++;
148 } // We have a charged PFO
149 } // Loop on jet constituents
150 } else if (ctype == xAOD::Type::FlowElement) {
151 // This jet is made from xAOD::FlowElement, so we calculate the pflow moments if they're PFOs
152 size_t numConstit = jet->numConstituents();
153 for (size_t i = 0; i < numConstit; i++) {
154 const xAOD::FlowElement *constit = dynamic_cast<const xAOD::FlowElement *>(jet->rawConstituent(i));
155 // UFO jet constituents have signalType xAOD::FlowElement::Charged or xAOD::FlowElement::Neutral
156 // PFlow jet constituents have signalType xAOD::FlowElement::ChargedPFlow or xAOD::FlowElement::NeutralPFlow
157 if (constit != nullptr && ((constit->signalType() & xAOD::FlowElement::PFlow) || constit->signalType() == xAOD::FlowElement::Charged)) {
158 if (constit->isCharged()) {
159 const xAOD::TrackParticle *thisTrack = dynamic_cast<const xAOD::TrackParticle *>( constit->chargedObject( 0)); // PFO should have only 1 track
160 if (thisTrack != nullptr) {
161 trackKey.emplace_back(DataType(thisTrack->index()));
162 trackContKey.emplace_back(m_tracksName.value());
163 trackcounter++;
164 }
165 else
166 ATH_MSG_WARNING( "Charged PFO had no associated TrackParticle");
167 } // We have a charged PFO
168 } // The FlowElement is a PFO
169 } // Loop on jet constituents
170 } else if (ctype == xAOD::Type::CaloCluster) {
171 // get associated cluster
172 for (size_t j = 0; j < numConstit; ++j) {
173 const xAOD::CaloCluster *cluster = static_cast<const xAOD::CaloCluster *>(jet->rawConstituent(j));
174 clusterID.emplace_back(DataType(cluster->index()));
175 if(!cluster->getCellLinks())continue;
176 for (const auto cc : *(cluster->getCellLinks())) {
177 if (std::find(tempCellID.begin(), tempCellID.end(), std::to_string( cc->caloDDE()->identify().get_compact())) != tempCellID.end()) {
178 continue;
179 } else {
180 cellID.emplace_back( DataType(cc->caloDDE()->identify().get_compact()));
181 tempCellID.emplace_back( std::to_string(cc->caloDDE()->identify().get_compact()));
182 }
183 }
184 ATH_MSG_VERBOSE(" Associated cluster: eta = " << cluster->eta() << ", phi = " << cluster->phi());
185 }
186 // get ghost associated tracks
187 std::vector<const xAOD::TrackParticle*> ghosttracks;
188 jet->getAssociatedObjects<xAOD::TrackParticle>(xAOD::JetAttribute::GhostTrack, ghosttracks);
189 if (ghosttracks.empty()) {
190 ATH_MSG_VERBOSE(" Associated track: ERROR");
191 } else {
192 for (size_t i = 0; i < ghosttracks.size(); i++) {
193
194 // can access the base track class, should be able to get tracker hits ?
195 // const Trk::Track* baseTrack = dynamic_cast< const Trk::Track* >( ghosttracks[i]->track());
196
197 trackKey.emplace_back(DataType(ghosttracks[i]->index()));
198 trackContKey.emplace_back(m_tracksName.value());
199
200 ATH_MSG_VERBOSE(" Associated track: d0 = " << ghosttracks[i]->d0() << ", pt = " << ghosttracks[i]->pt());
201 }
202 trackcounter = ghosttracks.size();
203 }
204 } else if (ctype == xAOD::Type::TrackParticle) {
205 for (size_t j = 0; j < numConstit; ++j) {
206 const xAOD::TrackParticle *track =
207 dynamic_cast<const xAOD::TrackParticle *>(jet->rawConstituent(j));
208 if (!track) {
209 ATH_MSG_VERBOSE(" Associated track: ERROR");
210 } else {
211 trackKey.emplace_back(DataType(track->index()));
212 trackContKey.emplace_back(m_tracksName.value());
213 trackcounter++;
214 ATH_MSG_VERBOSE(" Associated track: d0 = " << track->d0() << ", pt = " << track->pt());
215 }
216 }
217 }
218 }
219 }
220 trackLinkCount.emplace_back(DataType(trackcounter));
221 numCells.emplace_back(DataType(tempCellID.size()));
222
223
224 phi.emplace_back(DataType(jet->phi()));
225 eta.emplace_back(DataType(jet->eta()));
226 et.emplace_back(DataType(jet->pt()/GeV)); // hack ! no et in xAOD_Jet_v1 currently
227 idVec.emplace_back( DataType( ++id ));
228
229 mass.emplace_back(DataType(jet->m()/GeV));
230 energy.emplace_back( DataType(jet->e()/GeV ) );
231
232 px.emplace_back(DataType(jet->px()/GeV));
233 py.emplace_back(DataType(jet->py()/GeV));
234 pz.emplace_back(DataType(jet->pz()/GeV));
235
236 // bjet tagger values
237 if (jetkey!="AntiKt4EMPFlowJets" || (m_nTaggers==0)){
238 for (auto taggerName : m_bTaggerNames) {
239 bTagName.emplace_back(DataType("None"));
240 bTagValue.emplace_back(DataType(0.));
241 }
242 }else{
243 double btagValue;
244 for (auto taggerName : m_bTaggerNames) {
245 CP::CorrectionCode code = m_btagSelTools[taggerName]->getTaggerWeight(*jet, btagValue);
246 if (code != CP::CorrectionCode::Ok) {
247 ATH_MSG_DEBUG("Failed to get btagging weight for tagger " << taggerName);
248 btagValue = 0;
249 }
250 bTagName.emplace_back(DataType(taggerName));
251 bTagValue.emplace_back(DataType(btagValue));
252 }
253 }
254
255 float chargeread;
256 if (!jet->getAttribute<float>(xAOD::JetAttribute::Charge, chargeread)) {
257 ATH_MSG_DEBUG("Jet charge unavailable!");
258 charge.emplace_back( DataType( 0. ));
259 }else{
260 charge.emplace_back( DataType( chargeread ));
261 }
262
263 // updated for data15
264 // from: Reconstruction/MET/METReconstruction/Root/METJetFilterTool.cxx
265 std::vector<float> jvfread;
266 if(!jet->getAttribute<std::vector<float> >(xAOD::JetAttribute::JVF,jvfread)) {
267 ATH_MSG_DEBUG("Jet JVF unavailable!");
268 jvf.emplace_back( DataType( 1. ));
269 }else{
270 jvf.emplace_back( DataType( jvfread[0] ));
271 }
272
273 float jvtread;
274 if(!jet->getAttribute<float>(xAOD::JetAttribute::Jvt,jvtread)) {
275 ATH_MSG_DEBUG("Jet JVT unavailable!");
276 jvt.emplace_back(DataType(0.));
277 } else {
278 jvt.emplace_back(DataType(jvtread));
279 }
280
281 float emfracread = 0;
282 if(!jet->getAttribute(xAOD::JetAttribute::EMFrac,emfracread)) {
283 ATH_MSG_DEBUG("Jet EMFrac unavailable!");
284 emfrac.emplace_back( DataType( 0. ));
285 }else{
286 emfrac.emplace_back( DataType( emfracread ));
287 }
288
289 } // end loop
290
291 // four-vectors
292 const std::size_t nphi = phi.size();
293 DataMap["phi"] = std::move(phi);
294 DataMap["eta"] = std::move(eta);
295 DataMap["et"] = std::move(et);
296 DataMap["energy"] = std::move(energy);
297 DataMap["mass"] = std::move(mass);
298 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
299 DataMap["bTagName multiple=\""+str_nTaggers+"\""] = std::move(bTagName); // assigned by hand !
300 DataMap["bTagValue multiple=\""+str_nTaggers+"\""] = std::move(bTagValue);
301 DataMap["charge"] = std::move(charge);
302 DataMap["id"] = std::move(idVec);
303 DataMap["px"] = std::move(px);
304 DataMap["py"] = std::move(py);
305 DataMap["pz"] = std::move(pz);
306 DataMap["jvf"] = std::move(jvf);
307 DataMap["jvt"] = std::move(jvt);
308 DataMap["emfrac"] = std::move(emfrac);
309
310 if (!trackKey.empty()){
311 double NTracksPerVertex = trackKey.size()*1./jetCont->size();
312 std::string tag = "trackIndex multiple=\"" +DataType(NTracksPerVertex).toString()+"\"";
313 DataMap[tag] = std::move(trackKey);
314 tag = "trackKey multiple=\"" +DataType(NTracksPerVertex).toString()+"\"";
315 DataMap[tag] = std::move(trackContKey);
316 }
317
318 if (!clusterID.empty()){
319 std::string tag = "clusterIndex multiple=\"" + DataType(clusterID.size()).toString()+"\"";
320 double NCellsPerJet = cellID.size()*1./jetCont->size();
321 tag = "cells multiple=\"" +DataType(NCellsPerJet).toString()+"\"";
322 DataMap[tag] = std::move(cellID);
323 }
324
325 DataMap["trackLinkCount"] = std::move(trackLinkCount);
326 DataMap["numCells"] = std::move(numCells);
327
328 ATH_MSG_DEBUG( dataTypeName() << " retrieved with " << nphi << " entries" );
329
330 return DataMap;
331 }
332
333
334} // 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_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
double charge(const T &p)
Definition AtlasPID.h:1003
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
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
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.