ATLAS Offline Software
JetCaloEnergies.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 
9 
11 #include "PFlowUtils/FEHelpers.h"
12 
14 #include "xAODPFlow/PFO.h"
15 #include "xAODPFlow/FlowElement.h"
16 
17 #include <memory>
18 #include <vector>
19 
20 //**********************************************************************
21 
23 : AsgTool(name) { }
24 
25 //**********************************************************************
26 
27 bool JetCaloEnergies::isInVector(const std::string& key, const std::vector<std::string>& calculations) {
28  // Split key to get back the actual handle key
29  std::vector<std::string> split;
30  std::string sub_string;
31  std::istringstream tokenStream(key);
32 
33  while (std::getline(tokenStream, sub_string, '.'))
34  {
35  split.push_back(sub_string);
36  }
37 
38  // Return true if handle key in list of calculations
39  return std::find(calculations.begin(), calculations.end(), split[1]) != calculations.end();
40 }
41 
43  ATH_MSG_INFO("Initializing JetCaloEnergies " << name());
44 
45  if(m_jetContainerName.empty()){
46  ATH_MSG_ERROR("JetCaloEnergies needs to have its input jet container configured!");
47  return StatusCode::FAILURE;
48  }
49 
59 
73  }
74 
75  // Init calo based variables if necessary
83 
85 
88 
89  // Init standard variables if necessary
102 
103  return StatusCode::SUCCESS;
104 }
105 
106 //**********************************************************************
107 
109  ATH_MSG_VERBOSE("Begin decorating jets.");
110  for(const xAOD::Jet* jet : jets) {
112  size_t numConstit = jet->numConstituents();
113  ePerSamplingHandle(*jet) = std::vector<float>(CaloSampling::Unknown, 0.);
114  std::vector<float>& ePerSampling = ePerSamplingHandle(*jet);
115  for ( float& e : ePerSampling ) e = 0.0; // re-initialize
116 
117  if ( numConstit == 0 ) {
118  ATH_MSG_VERBOSE("Jet has no constituents.");
119  continue;
120  }
121 
122  // should find a more robust solution than using 1st constit type.
123  xAOD::Type::ObjectType ctype = jet->rawConstituent( 0 )->type();
124  if ( ctype == xAOD::Type::CaloCluster ) {
125  ATH_MSG_VERBOSE(" Constituents are calo clusters.");
126  fillEperSamplingCluster(*jet, ePerSampling);
127 
128  } else if (ctype == xAOD::Type::ParticleFlow) {
129  ATH_MSG_VERBOSE(" Constituents are pflow objects.");
130  fillEperSamplingPFO(*jet, ePerSampling);
131 
132  } else if (ctype == xAOD::Type::FlowElement) {
133  ATH_MSG_VERBOSE(" Constituents are FlowElements.");
134  fillEperSamplingFE(*jet, ePerSampling);
135 
136  // In addition, calculate variables using the underlying cluster rather than
137  // the energy-subtracted FlowElements (improved implementation)
139  ATH_MSG_VERBOSE(" Constituents are FlowElements - Additional calculation");
140 
142  ePerSamplingClusterHandle(*jet) = std::vector<float>(CaloSampling::Unknown, 0.);
143  std::vector<float>& ePerSamplingCluster = ePerSamplingClusterHandle(*jet);
144  for ( float& e : ePerSamplingCluster ) e = 0.0; // re-initialize
145 
146  fillEperSamplingFEClusterBased(*jet, ePerSamplingCluster);
147  }
148 
149  }else {
150  ATH_MSG_VERBOSE("Constituents are not CaloClusters, PFOs, or FlowElements.");
151  }
152 
153  }
154  return StatusCode::SUCCESS;
155 }
156 
157 void JetCaloEnergies::fillEperSamplingCluster(const xAOD::Jet& jet, std::vector<float> & ePerSampling ) const {
158  // loop over raw constituents
159  size_t numConstit = jet.numConstituents();
160  for ( size_t i=0; i<numConstit; i++ ) {
161  if(jet.rawConstituent(i)->type()!=xAOD::Type::CaloCluster) {
162  ATH_MSG_WARNING("Tried to call fillEperSamplingCluster with a jet constituent that is not a cluster!");
163  continue;
164  }
165  const xAOD::CaloCluster* constit = static_cast<const xAOD::CaloCluster*>(jet.rawConstituent(i));
166  for ( size_t s= CaloSampling::PreSamplerB; s< CaloSampling::Unknown; s++ ) {
167  ePerSampling[s] += constit->eSample( (xAOD::CaloCluster::CaloSample) s );
168  }
169  }
170 
171  double fracSamplingMax = -999999999.;
172  int fracSamplingMaxIndex = -1;
173  double sumE_samplings = 0.0;
174 
176  for(unsigned int i = 0; i < ePerSampling.size(); ++i){
177  double e = ePerSampling[i];
178  sumE_samplings += e;
179  if (e>fracSamplingMax){
180  fracSamplingMax=e;
181  fracSamplingMaxIndex = i;
182  }
183  }
184  }
185 
189 
190  emFracHandle(jet) = jet::JetCaloQualityUtils::emFraction( ePerSampling );
191  hecFracHandle(jet) = jet::JetCaloQualityUtils::hecF( &jet );
193 
196  fracSamplingMaxHandle(jet) = sumE_samplings != 0. ? fracSamplingMax/sumE_samplings : 0.;
198  fracSamplingMaxIndexHandle(jet) = fracSamplingMaxIndex;
199  }
200 }
201 
202 #define FillESamplingPFO( LAYERNAME ) \
203  float E_##LAYERNAME = 0.0; \
204  if (constit->attribute(xAOD::PFODetails::eflowRec_LAYERENERGY_##LAYERNAME, E_##LAYERNAME)) { \
205  ePerSampling[CaloSampling::LAYERNAME] += E_##LAYERNAME; \
206  }
207 
208 void JetCaloEnergies::fillEperSamplingPFO(const xAOD::Jet & jet, std::vector<float> & ePerSampling ) const {
209 
210  float emTot=0;
211  float hecTot=0;
212  float eTot =0;
213  size_t numConstit = jet.numConstituents();
214 
215  for ( size_t i=0; i<numConstit; i++ ) {
216  if (jet.rawConstituent(i)->type()==xAOD::Type::ParticleFlow){
217  const xAOD::PFO* constit = static_cast<const xAOD::PFO*>(jet.rawConstituent(i));
218  if ( fabs(constit->charge())>FLT_MIN ){
219  eTot += constit->track(0)->e();
220  } else {
221  eTot += constit->e();
226 
231 
236 
240 
244 
248 
252 
253  FillESamplingPFO(MINIFCAL0);
254  FillESamplingPFO(MINIFCAL1);
255  FillESamplingPFO(MINIFCAL2);
256  FillESamplingPFO(MINIFCAL3);
257 
258  emTot += ( E_PreSamplerB+E_EMB1+E_EMB2+E_EMB3+
259  E_PreSamplerE+E_EME1+E_EME2+E_EME3+
260  E_FCAL0 );
261  hecTot += ( E_HEC0+E_HEC1+E_HEC2+E_HEC3 );
262 
263  }//only consider neutral PFO
264  } else {
265  ATH_MSG_WARNING("Tried to call fillEperSamplingPFlow with a jet constituent that is not a PFO!");
266  }
267  }
268 
270  if(eTot != 0.0){
271  emFracHandle(jet) = emTot/eTot;
272  /*
273  * Ratio of EM layer calorimeter energy of neutrals to sum of all constituents
274  * at EM scale (note charged PFO have an EM scale at track scale, and charged weights are ignored)
275  * */
276  }
277  else {
278  emFracHandle(jet) = 0.;
279  }
280 
282  if (eTot != 0.0){
283  hecFracHandle(jet) = hecTot/eTot;
284  }
285  else{
286  hecFracHandle(jet) = 0.;
287  }
288 
289 }
290 
291 // R21 way of calculating energy-per-layer using directly the FE decorations
292 // In R21, the link from PFOs to clusters was broken and thus energy after charged subtraction was used
293 void JetCaloEnergies::fillEperSamplingFE(const xAOD::Jet& jet, std::vector<float> & ePerSampling ) const {
294  float emTot = 0.;
295  float em3Tot = 0.;
296  float hecTot = 0.;
297  float psTot = 0.;
298  float tile0Tot = 0.;
299  float eTot = 0.;
300  float e2Tot = 0.;
301  size_t numConstit = jet.numConstituents();
302 
303  std::vector<int> indicesNeutralFE;
304  std::vector<int> indicesChargedFE;
305 
306  for ( size_t i=0; i<numConstit; i++ ) {
307  if(jet.rawConstituent(i)->type()!=xAOD::Type::FlowElement) {
308  ATH_MSG_WARNING("Tried to call fillEperSamplingFE with a jet constituent that is not a FlowElement!");
309  continue;
310  }
311  const xAOD::FlowElement* constit = static_cast<const xAOD::FlowElement*>(jet.rawConstituent(i));
312 
313  // Need to distinguish two cases:
314  // (1) Jet is a PFlow jet (constituents are charged or neutral FEs) or
315  // (2) Jet is a UFO jet (need to get the underlying charged and neutral FEs first)
316 
317  //For PFlow jets, we can directly get the information from the constituent
318  if(constit->signalType() & xAOD::FlowElement::PFlow){
319 
320  //Charged FlowElements:
321  if(constit->isCharged()){
322  eTot += constit->chargedObject(0)->e();
323  e2Tot += constit->chargedObject(0)->e()*constit->chargedObject(0)->e();
324  }
325  //Neutral FlowElements
326  else{
327  eTot += constit->e();
328  e2Tot += constit->e()*constit->e();
329  //Get the energy-per-layer information from the FE, not the underlying cluster (i.e. after subtraction)
330  std::vector<float> constitEPerSampling = FEHelpers::getEnergiesPerSampling(*constit);
331  for ( size_t s = CaloSampling::PreSamplerB; s < CaloSampling::Unknown; s++ ) {
332  ePerSampling[s] += constitEPerSampling[s];
333  }
334  emTot += (constitEPerSampling[CaloSampling::PreSamplerB] + constitEPerSampling[CaloSampling::EMB1]
335  + constitEPerSampling[CaloSampling::EMB2] + constitEPerSampling[CaloSampling::EMB3]
336  + constitEPerSampling[CaloSampling::PreSamplerE] + constitEPerSampling[CaloSampling::EME1]
337  + constitEPerSampling[CaloSampling::EME2] + constitEPerSampling[CaloSampling::EME3]
338  + constitEPerSampling[CaloSampling::FCAL0]);
339 
340  hecTot += (constitEPerSampling[CaloSampling::HEC0] + constitEPerSampling[CaloSampling::HEC1]
341  + constitEPerSampling[CaloSampling::HEC2] + constitEPerSampling[CaloSampling::HEC3]);
342 
343  psTot += (constitEPerSampling[CaloSampling::PreSamplerB] + constitEPerSampling[CaloSampling::PreSamplerE]);
344 
345  em3Tot += (constitEPerSampling[CaloSampling::EMB3] + constitEPerSampling[CaloSampling::EME3]);
346 
347  tile0Tot += (constitEPerSampling[CaloSampling::TileBar0] + constitEPerSampling[CaloSampling::TileExt0]);
348  }
349  }
350  else{
351  //For UFO jets, we first need to get the charged and neutral FE + corresponding energy from combined UFOs
352 
353  // UFO is simply a charged FlowElement
354  if(constit->signalType() == xAOD::FlowElement::Charged){
355  eTot += constit->chargedObject(0)->e();
356  e2Tot += constit->chargedObject(0)->e()*constit->chargedObject(0)->e();
357  }
358  //UFO is simply a neutral Flowelement
359  else if(constit->signalType() == xAOD::FlowElement::Neutral){
360  // For neutral UFOs, there is only one "other object" stored which is the neutral FE
361  // Protection in case there is something wrong with this FE
362  if(constit->otherObjects().size() != 1 || !constit->otherObject(0)){
363  continue;
364  }
365 
366  // Cast other object as FlowElement
367  const xAOD::FlowElement* nFE = static_cast<const xAOD::FlowElement*>(constit->otherObject(0));
368 
369  eTot += nFE->e();
370  e2Tot += nFE->e()*nFE->e();
371 
372  std::vector<float> neutralEPerSampling = FEHelpers::getEnergiesPerSampling(*nFE);
373  for ( size_t s = CaloSampling::PreSamplerB; s < CaloSampling::Unknown; s++ ) {
374  ePerSampling[s] += neutralEPerSampling[s];
375  }
376  emTot += (neutralEPerSampling[CaloSampling::PreSamplerB] + neutralEPerSampling[CaloSampling::EMB1]
377  + neutralEPerSampling[CaloSampling::EMB2] + neutralEPerSampling[CaloSampling::EMB3]
378  + neutralEPerSampling[CaloSampling::PreSamplerE] + neutralEPerSampling[CaloSampling::EME1]
379  + neutralEPerSampling[CaloSampling::EME2] + neutralEPerSampling[CaloSampling::EME3]
380  + neutralEPerSampling[CaloSampling::FCAL0]);
381 
382  hecTot += (neutralEPerSampling[CaloSampling::HEC0] + neutralEPerSampling[CaloSampling::HEC1]
383  + neutralEPerSampling[CaloSampling::HEC2] + neutralEPerSampling[CaloSampling::HEC3]);
384 
385  psTot += (neutralEPerSampling[CaloSampling::PreSamplerB] + neutralEPerSampling[CaloSampling::PreSamplerE]);
386 
387  em3Tot += (neutralEPerSampling[CaloSampling::EMB3] + neutralEPerSampling[CaloSampling::EME3]);
388 
389  tile0Tot += (neutralEPerSampling[CaloSampling::TileBar0] + neutralEPerSampling[CaloSampling::TileExt0]);
390  }
391  else if(constit->signalType() == xAOD::FlowElement::Combined){
392  // For the combined UFOs, otherObjects are neutral or charged FEs
393  // matched to this tracks (via track-to-cluster extrapolation)
394  for (size_t n = 0; n < constit->otherObjects().size(); ++n) {
395  if(! constit->otherObject(n)) continue;
396  const xAOD::FlowElement* FE_from_combined = static_cast<const xAOD::FlowElement*>(constit->otherObject(n));
397 
398  //Charged FE (add energy to total energy only)
399  if(FE_from_combined->isCharged()){
400  if(std::find(indicesChargedFE.begin(), indicesChargedFE.end(), FE_from_combined->index()) == indicesChargedFE.end()){
401  eTot += FE_from_combined->e();
402  e2Tot += FE_from_combined->e()*FE_from_combined->e();
403  indicesChargedFE.push_back(FE_from_combined->index());
404  }
405  continue;
406  }
407  //Neutral FE:
408  //One neutral FE can be matched to various tracks and therefore be used for several UFOs
409  //We do not want to double count the energy and only add it once
410  if(std::find(indicesNeutralFE.begin(), indicesNeutralFE.end(), FE_from_combined->index()) == indicesNeutralFE.end()){
411  eTot += FE_from_combined->e();
412  e2Tot += FE_from_combined->e()*FE_from_combined->e();
413  std::vector<float> neutralFromCombEPerSampling = FEHelpers::getEnergiesPerSampling(*FE_from_combined);
414  for ( size_t s = CaloSampling::PreSamplerB; s < CaloSampling::Unknown; s++ ) {
415  ePerSampling[s] += neutralFromCombEPerSampling[s];
416  }
417  emTot += (neutralFromCombEPerSampling[CaloSampling::PreSamplerB] + neutralFromCombEPerSampling[CaloSampling::EMB1]
418  + neutralFromCombEPerSampling[CaloSampling::EMB2] + neutralFromCombEPerSampling[CaloSampling::EMB3]
419  + neutralFromCombEPerSampling[CaloSampling::PreSamplerE] + neutralFromCombEPerSampling[CaloSampling::EME1]
420  + neutralFromCombEPerSampling[CaloSampling::EME2] + neutralFromCombEPerSampling[CaloSampling::EME3]
421  + neutralFromCombEPerSampling[CaloSampling::FCAL0]);
422 
423  hecTot += (neutralFromCombEPerSampling[CaloSampling::HEC0] + neutralFromCombEPerSampling[CaloSampling::HEC1]
424  + neutralFromCombEPerSampling[CaloSampling::HEC2] + neutralFromCombEPerSampling[CaloSampling::HEC3]);
425 
426  psTot += (neutralFromCombEPerSampling[CaloSampling::PreSamplerB] + neutralFromCombEPerSampling[CaloSampling::PreSamplerE]);
427 
428  em3Tot += (neutralFromCombEPerSampling[CaloSampling::EMB3] + neutralFromCombEPerSampling[CaloSampling::EME3]);
429 
430  tile0Tot += (neutralFromCombEPerSampling[CaloSampling::TileBar0] + neutralFromCombEPerSampling[CaloSampling::TileExt0]);
431 
432  indicesNeutralFE.push_back(FE_from_combined->index());
433  }
434  }
435  }
436  }
437  }
438 
439  double fracSamplingMax = -999999999.;
440  int fracSamplingMaxIndex = -1;
441  double sumE_samplings = 0.0;
442 
444  for(unsigned int i = 0; i < ePerSampling.size(); ++i){
445  double e = ePerSampling[i];
446  sumE_samplings += e;
447  if (e>fracSamplingMax){
448  fracSamplingMax=e;
449  fracSamplingMaxIndex = i;
450  }
451  }
452  }
453 
454  for( const std::string & calcN : m_calculationNames){
455  if ( calcN == "EMFrac" ) {
457  emFracHandle(jet) = eTot != 0. ? emTot/eTot : 0.;
458  } else if ( calcN == "HECFrac" ) {
460  hecFracHandle(jet) = eTot != 0. ? hecTot/eTot : 0.;
461  } else if ( calcN == "PSFrac" ) {
463  psFracHandle(jet) = eTot != 0. ? psTot/eTot : 0.;
464  } else if ( calcN == "EM3Frac" ) {
466  em3FracHandle(jet) = eTot != 0. ? em3Tot/eTot : 0.;
467  } else if ( calcN == "Tile0Frac" ) {
469  tile0FracHandle(jet) = eTot != 0. ? tile0Tot/eTot : 0.;
470  } else if ( calcN == "EffNClusts" ) {
472  effNClustsFracHandle(jet) = eTot != 0. ? std::sqrt(eTot*eTot/e2Tot) : 0.;
473  } else if ( calcN == "FracSamplingMax" ){
475  fracSamplingMaxHandle(jet) = sumE_samplings != 0. ? fracSamplingMax/sumE_samplings : 0.;
477  fracSamplingMaxIndexHandle(jet) = fracSamplingMaxIndex;
478  }
479  }
480 }
481 
482 
483 // New way of calculating energy per layer for FE-based jets
484 // The underlying cluster is used to calculate the variables rather than the energy-subtracted FE
485 void JetCaloEnergies::fillEperSamplingFEClusterBased(const xAOD::Jet& jet, std::vector<float> & ePerSampling ) const {
486  float emTot = 0.;
487  float em3Tot = 0.;
488  float hecTot = 0.;
489  float psTot = 0.;
490  float tile0Tot = 0.;
491  float eTot = 0.;
492  float e2Tot = 0.;
493  float sumRadialDistanceSquared = 0;
494  float sumLongitudinalDistanceSquared = 0;
495  size_t numConstit = jet.numConstituents();
496  std::unique_ptr<std::vector<const xAOD::CaloCluster*> > constitV_tot = std::make_unique<std::vector<const xAOD::CaloCluster*>>();
497  const xAOD::CaloCluster* leadingCluster = nullptr;
498 
499  for ( size_t i=0; i<numConstit; i++ ) {
500  if(jet.rawConstituent(i)->type()!=xAOD::Type::FlowElement) {
501  ATH_MSG_WARNING("Tried to call fillEperSamplingFE with a jet constituent that is not a FlowElement!");
502  continue;
503  }
504  const xAOD::FlowElement* constit = static_cast<const xAOD::FlowElement*>(jet.rawConstituent(i));
505 
506  for (size_t n = 0; n < constit->otherObjects().size(); ++n) {
507  if(! constit->otherObject(n)) continue;
508  int index_pfo = constit->otherObject(n)->index();
509  if(index_pfo<0) continue;
510 
511  const auto* fe = (constit->otherObject(n));
512  const xAOD::CaloCluster* cluster = nullptr;
513 
514  //If we have a cluster, we can directly access the calorimeter information
515  if(fe->type() == xAOD::Type::CaloCluster){
516  cluster = dynamic_cast<const xAOD::CaloCluster*> (fe);
517  }
518  //If we have a PFO, we should still get the associated cluster first
519  else {
520  const xAOD::FlowElement* pfo = dynamic_cast<const xAOD::FlowElement*>(fe);
521  if(!pfo->otherObjects().empty() && pfo->otherObject(0) && pfo->otherObject(0)->type() == xAOD::Type::CaloCluster){
522  cluster = dynamic_cast<const xAOD::CaloCluster*> (pfo->otherObject(0));
523  }
524  }
525  if(!cluster) continue;
526 
527  if (!leadingCluster || (cluster->rawE() > leadingCluster->rawE())){
528  leadingCluster = cluster;
529  }
530 
531 
532  if(std::find(constitV_tot->begin(), constitV_tot->end(), cluster) == constitV_tot->end()){
533  for ( size_t s= CaloSampling::PreSamplerB; s< CaloSampling::Unknown; s++ ) {
534  ePerSampling[s] += cluster->eSample( (xAOD::CaloCluster::CaloSample) s );
535  }
536  eTot += cluster->rawE();
537  e2Tot += cluster->rawE()*cluster->rawE();
538 
539  emTot += (cluster->eSample( CaloSampling::PreSamplerB) + cluster->eSample( CaloSampling::EMB1)
540  + cluster->eSample( CaloSampling::EMB2) + cluster->eSample( CaloSampling::EMB3)
542  + cluster->eSample( CaloSampling::EME2) + cluster->eSample( CaloSampling::EME3)
543  + cluster->eSample( CaloSampling::FCAL0));
544 
545  hecTot += (cluster->eSample( CaloSampling::HEC0) + cluster->eSample( CaloSampling::HEC1)
546  + cluster->eSample( CaloSampling::HEC2) + cluster->eSample( CaloSampling::HEC3));
547 
548  psTot += (cluster->eSample( CaloSampling::PreSamplerB) + cluster->eSample( CaloSampling::PreSamplerE));
549 
550  em3Tot += (cluster->eSample( CaloSampling::EMB3) + cluster->eSample( CaloSampling::EME3));
551 
552  tile0Tot += (cluster->eSample( CaloSampling::TileBar0) + cluster->eSample( CaloSampling::TileExt0));
553 
554  sumRadialDistanceSquared += cluster->rawE() * getMoment(cluster, xAOD::CaloCluster::SECOND_R);
555  sumLongitudinalDistanceSquared += cluster->rawE() * getMoment(cluster, xAOD::CaloCluster::SECOND_LAMBDA);
556 
557  constitV_tot->push_back(cluster);
558  }
559  }
560  }
561 
562  float fracSamplingMax = -999999999.;
563  int fracSamplingMaxIndex = -1;
564  float sumE_samplings = 0.0;
565 
567  for(unsigned int i = 0; i < ePerSampling.size(); ++i){
568  float e = ePerSampling[i];
569  sumE_samplings += e;
570  if (e>fracSamplingMax){
571  fracSamplingMax=e;
572  fracSamplingMaxIndex = i;
573  }
574  }
575  }
576 
577  for( const std::string & calcN : m_calculationNames){
578  if ( calcN == "EMFrac" ) {
580  emFracClusterHandle(jet) = eTot != 0. ? emTot/eTot : 0.;
581  } else if ( calcN == "HECFrac" ) {
583  hecFracClusterHandle(jet) = eTot != 0. ? hecTot/eTot : 0.;
584  } else if ( calcN == "PSFrac" ) {
586  psFracClusterHandle(jet) = eTot != 0. ? psTot/eTot : 0.;
587  } else if ( calcN == "EM3Frac" ) {
589  em3FracClusterHandle(jet) = eTot != 0. ? em3Tot/eTot : 0.;
590  } else if ( calcN == "Tile0Frac" ) {
592  tile0FracClusterHandle(jet) = eTot != 0. ? tile0Tot/eTot : 0.;
593  } else if ( calcN == "EffNClusts" ) {
595  effNClustsFracClusterHandle(jet) = eTot != 0. ? std::sqrt(eTot*eTot/e2Tot) : 0.;
596  } else if ( calcN == "FracSamplingMax" ){
598  fracSamplingMaxClusterHandle(jet) = sumE_samplings != 0. ? fracSamplingMax/sumE_samplings : 0.;
600  fracSamplingMaxIndexClusterHandle(jet) = fracSamplingMaxIndex;
601  }
602  }
603 
605  lambdaLeadingClusterHandle(jet) = getMoment(leadingCluster, xAOD::CaloCluster::CENTER_LAMBDA);
606 
608  meanRadialDistanceSquaredHandle(jet) = eTot != 0. ? sumRadialDistanceSquared/eTot : 0.;
609 
611  meanLongitudinalDistanceSquaredHandle(jet) = eTot != 0. ? sumLongitudinalDistanceSquared/eTot : 0.;
612 }
613 
614 float JetCaloEnergies::getMoment(const xAOD::CaloCluster* cluster, const xAOD::CaloCluster::MomentType& momentType) const {
615  if (cluster){
616  double moment = 0.0;
617  bool isRetrieved = cluster->retrieveMoment(momentType, moment);
618  if (isRetrieved) return (float) moment;
619  }
620  ATH_MSG_WARNING("Can not retrieve moment from cluster");
621  return 0.0;
622 }
xAOD::CaloCluster_v1::SECOND_R
@ SECOND_R
Second Moment in .
Definition: CaloCluster_v1.h:126
JetCaloEnergies::m_fracSamplingMaxClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_fracSamplingMaxClusterKey
Definition: JetCaloEnergies.h:59
JetCaloEnergies::isInVector
bool isInVector(const std::string &key, const std::vector< std::string > &calculations)
Definition: JetCaloEnergies.cxx:27
xAOD::CaloCluster_v1::rawE
flt_t rawE() const
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
GetLCDefs::Unknown
@ Unknown
Definition: GetLCDefs.h:21
FEHelpers.h
JetCaloEnergies::m_effNClustsFracKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_effNClustsFracKey
Definition: JetCaloEnergies.h:47
xAOD::FlowElement_v1::Neutral
@ Neutral
Definition: FlowElement_v1.h:37
CaloCell_ID_FCS::TileExt2
@ TileExt2
Definition: FastCaloSim_CaloCell_ID.h:39
constants.EMB1
int EMB1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:53
JetCaloEnergies::m_jetContainerName
Gaudi::Property< std::string > m_jetContainerName
Definition: JetCaloEnergies.h:38
JetCaloEnergies::fillEperSamplingPFO
void fillEperSamplingPFO(const xAOD::Jet &jet, std::vector< float > &ePerSampling) const
Definition: JetCaloEnergies.cxx:208
xAOD::FlowElement_v1::Charged
@ Charged
Definition: FlowElement_v1.h:38
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
ObjectType
ObjectType
Definition: BaseObject.h:11
CaloCell_ID_FCS::TileExt0
@ TileExt0
Definition: FastCaloSim_CaloCell_ID.h:37
xAOD::PFO_v1::track
const TrackParticle * track(unsigned int index) const
Retrieve a const pointer to a Rec::TrackParticle.
Definition: PFO_v1.cxx:691
CaloCell_ID_FCS::TileBar1
@ TileBar1
Definition: FastCaloSim_CaloCell_ID.h:32
JetCaloEnergies::m_em3FracClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_em3FracClusterKey
Definition: JetCaloEnergies.h:56
JetCaloEnergies::JetCaloEnergies
JetCaloEnergies(const std::string &t)
Definition: JetCaloEnergies.cxx:22
JetCaloEnergies::initialize
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: JetCaloEnergies.cxx:42
JetCaloEnergies::m_doFracSamplingMax
bool m_doFracSamplingMax
Definition: JetCaloEnergies.h:34
CaloCell_ID_FCS::FCAL1
@ FCAL1
Definition: FastCaloSim_CaloCell_ID.h:41
JetCaloEnergies::m_fracSamplingMaxIndexKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_fracSamplingMaxIndexKey
Definition: JetCaloEnergies.h:49
defineDB.jets
jets
Definition: JetTagCalibration/share/defineDB.py:24
xAOD::IParticle::type
virtual Type::ObjectType type() const =0
The type of the object as a simple enumeration.
xAOD::CaloCluster_v1::CENTER_LAMBDA
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
Definition: CaloCluster_v1.h:139
JetCaloEnergies::fillEperSamplingFE
void fillEperSamplingFE(const xAOD::Jet &jet, std::vector< float > &ePerSampling) const
Definition: JetCaloEnergies.cxx:293
CaloCell_ID_FCS::HEC2
@ HEC2
Definition: FastCaloSim_CaloCell_ID.h:29
IDTPM::eTot
float eTot(const U &p)
Accessor utility function for getting the value of Energy.
Definition: TrackParametersHelper.h:118
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
JetCaloEnergies::decorate
virtual StatusCode decorate(const xAOD::JetContainer &jets) const override
Decorate a jet collection without otherwise modifying it.
Definition: JetCaloEnergies.cxx:108
FEHelpers::getEnergiesPerSampling
std::vector< float > getEnergiesPerSampling(const xAOD::FlowElement &fe)
Definition: FEHelpers.cxx:78
CaloCell_ID_FCS::TileGap3
@ TileGap3
Definition: FastCaloSim_CaloCell_ID.h:36
JetCaloEnergies::m_tile0FracKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_tile0FracKey
Definition: JetCaloEnergies.h:46
JetAccessorMap.h
xAOD::CaloCluster
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloCluster.h:19
JetCaloEnergies::m_ePerSamplingKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_ePerSamplingKey
Definition: JetCaloEnergies.h:41
xAOD::CaloCluster_v1::SECOND_LAMBDA
@ SECOND_LAMBDA
Second Moment in .
Definition: CaloCluster_v1.h:127
JetCaloEnergies::m_psFracClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_psFracClusterKey
Definition: JetCaloEnergies.h:55
xAOD::CaloCluster_v1::MomentType
MomentType
Enums to identify different moments.
Definition: CaloCluster_v1.h:123
JetCaloEnergies::m_ePerSamplingClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_ePerSamplingClusterKey
Definition: JetCaloEnergies.h:52
xAOD::FlowElement_v1::PFlow
@ PFlow
Definition: FlowElement_v1.h:45
xAOD::PFO_v1::e
virtual double e() const
The total energy of the particle.
Definition: PFO_v1.cxx:81
xAOD::FlowElement_v1::isCharged
bool isCharged() const
Definition: FlowElement_v1.cxx:56
PFO.h
JetCaloEnergies::m_hecFracClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_hecFracClusterKey
Definition: JetCaloEnergies.h:54
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
CaloCell_ID_FCS::HEC1
@ HEC1
Definition: FastCaloSim_CaloCell_ID.h:28
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
FlowElement.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
CaloCluster.h
CaloCell_ID_FCS::TileBar0
@ TileBar0
Definition: FastCaloSim_CaloCell_ID.h:31
beamspotman.n
n
Definition: beamspotman.py:729
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CaloCell_ID_FCS::TileGap2
@ TileGap2
Definition: FastCaloSim_CaloCell_ID.h:35
xAOD::FlowElement
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition: FlowElement.h:16
JetCaloEnergies::m_fracSamplingMaxKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_fracSamplingMaxKey
Definition: JetCaloEnergies.h:48
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
xAOD::PFO_v1::charge
float charge() const
get charge of PFO
xAOD::FlowElement_v1::signalType
signal_t signalType() const
JetCaloEnergies::m_meanLongitudinalDistanceSquaredKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_meanLongitudinalDistanceSquaredKey
Definition: JetCaloEnergies.h:64
JetCaloEnergies::m_fracSamplingMaxIndexClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_fracSamplingMaxIndexClusterKey
Definition: JetCaloEnergies.h:60
constants.EME1
int EME1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAODType::ParticleFlow
@ ParticleFlow
The object is a particle-flow object.
Definition: ObjectType.h:41
xAOD::CaloCluster_v1::retrieveMoment
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
Definition: CaloCluster_v1.cxx:692
SG::AuxElement::index
size_t index() const
Return the index of this element within its container.
JetCaloEnergies::m_tile0FracClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_tile0FracClusterKey
Definition: JetCaloEnergies.h:57
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
CaloCell_ID_FCS::TileGap1
@ TileGap1
Definition: FastCaloSim_CaloCell_ID.h:34
WriteDecorHandle.h
Handle class for adding a decoration to an object.
FillESamplingPFO
#define FillESamplingPFO(LAYERNAME)
Definition: JetCaloEnergies.cxx:202
xAOD::FlowElement_v1::chargedObject
const xAOD::IParticle * chargedObject(std::size_t i) const
Definition: FlowElement_v1.cxx:127
JetCaloEnergies::m_meanRadialDistanceSquaredKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_meanRadialDistanceSquaredKey
Definition: JetCaloEnergies.h:63
xAOD::PFO_v1
Class describing a particle flow object.
Definition: PFO_v1.h:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
CaloCell_ID_FCS::TileExt1
@ TileExt1
Definition: FastCaloSim_CaloCell_ID.h:38
CaloCell_ID_FCS::EME3
@ EME3
Definition: FastCaloSim_CaloCell_ID.h:26
xAOD::FlowElement_v1::e
virtual double e() const override
The total energy of the particle.
Definition: FlowElement_v1.cxx:25
JetCaloEnergies::m_effNClustsFracClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_effNClustsFracClusterKey
Definition: JetCaloEnergies.h:58
xAOD::TrackParticle_v1::e
virtual double e() const override final
The total energy of the particle.
Definition: TrackParticle_v1.cxx:110
JetCaloEnergies::m_calculationNames
Gaudi::Property< std::vector< std::string > > m_calculationNames
Definition: JetCaloEnergies.h:37
xAOD::FlowElement_v1::Combined
@ Combined
Definition: FlowElement_v1.h:39
CaloCell_ID_FCS::HEC0
@ HEC0
Definition: FastCaloSim_CaloCell_ID.h:27
JetCaloEnergies::m_emFracKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_emFracKey
Definition: JetCaloEnergies.h:42
JetCaloEnergies::m_emFracClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_emFracClusterKey
Definition: JetCaloEnergies.h:53
JetCaloEnergies::m_calcClusterBasedVars
Gaudi::Property< bool > m_calcClusterBasedVars
Definition: JetCaloEnergies.h:39
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
jet::JetCaloQualityUtils::hecF
static double hecF(const Jet *jet)
Definition: JetCaloQualityUtils.cxx:67
JetCaloEnergies.h
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:514
SG::WriteDecorHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CaloCell_ID_FCS::PreSamplerE
@ PreSamplerE
Definition: FastCaloSim_CaloCell_ID.h:23
CaloCell_ID_FCS::PreSamplerB
@ PreSamplerB
Definition: FastCaloSim_CaloCell_ID.h:19
xAOD::FlowElement_v1::otherObject
const xAOD::IParticle * otherObject(std::size_t i) const
Definition: FlowElement_v1.cxx:196
JetCaloEnergies::getMoment
float getMoment(const xAOD::CaloCluster *cluster, const xAOD::CaloCluster::MomentType &momentType) const
Definition: JetCaloEnergies.cxx:614
JetCaloEnergies::m_em3FracKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_em3FracKey
Definition: JetCaloEnergies.h:45
JetCaloEnergies::m_lambdaLeadingClusterKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_lambdaLeadingClusterKey
Definition: JetCaloEnergies.h:62
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
JetCaloEnergies::m_psFracKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_psFracKey
Definition: JetCaloEnergies.h:44
jet::JetCaloQualityUtils::emFraction
static double emFraction(const std::vector< float > &ePerSampling)
Definition: JetCaloQualityUtils.cxx:56
JetCaloEnergies::fillEperSamplingFEClusterBased
void fillEperSamplingFEClusterBased(const xAOD::Jet &jet, std::vector< float > &ePerSampling) const
Definition: JetCaloEnergies.cxx:485
JetCaloEnergies::m_hecFracKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_hecFracKey
Definition: JetCaloEnergies.h:43
CaloCell_ID_FCS::FCAL2
@ FCAL2
Definition: FastCaloSim_CaloCell_ID.h:42
JetCaloQualityUtils.h
JetCaloEnergies::fillEperSamplingCluster
void fillEperSamplingCluster(const xAOD::Jet &jet, std::vector< float > &ePerSampling) const
Definition: JetCaloEnergies.cxx:157
CaloCell_ID_FCS::HEC3
@ HEC3
Definition: FastCaloSim_CaloCell_ID.h:30
CaloCell_ID_FCS::FCAL0
@ FCAL0
Definition: FastCaloSim_CaloCell_ID.h:40
CaloCell_ID_FCS::EMB3
@ EMB3
Definition: FastCaloSim_CaloCell_ID.h:22
CaloCell_ID_FCS::TileBar2
@ TileBar2
Definition: FastCaloSim_CaloCell_ID.h:33
jet::JetCaloQualityUtils::presamplerFraction
static double presamplerFraction(const Jet *jet)
Definition: JetCaloQualityUtils.cxx:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
xAOD::IParticle::e
virtual double e() const =0
The total energy of the particle.
xAOD::FlowElement_v1::otherObjects
std::vector< const xAOD::IParticle * > otherObjects() const
Definition: FlowElement_v1.cxx:163
xAOD::FlowElement_v1
A detector object made of other lower level object(s)
Definition: FlowElement_v1.h:25
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37