ATLAS Offline Software
Loading...
Searching...
No Matches
PFNeutralFlowElementCreatorAlgorithm.cxx
Go to the documentation of this file.
7
9
12
13 return StatusCode::SUCCESS;
14}
15
16StatusCode PFNeutralFlowElementCreatorAlgorithm::execute(const EventContext& ctx) const {
17
18 ATH_MSG_DEBUG("Executing");
19
20 /* Create Neutral PFOs from all eflowCaloObjects */
21 SG::ReadHandle<eflowCaloObjectContainer> eflowCaloObjectContainerReadHandle(
23
24 // Always create at least one FlowElement container & aux
25 auto neutralFEContainer = std::make_unique<xAOD::FlowElementContainer>();
26 auto neutralFEContainerAux = std::make_unique<xAOD::FlowElementAuxContainer>();
27 neutralFEContainer->setStore(neutralFEContainerAux.get());
28
29 ATH_MSG_DEBUG("Looping over eflowCaloObjects");
30 // Create FlowElements and fill the containers
31 for (const auto *thisEflowCaloObject : *eflowCaloObjectContainerReadHandle) {
32 if( createNeutralFlowElement(*thisEflowCaloObject, neutralFEContainer.get()).isFailure()) {
33 ATH_MSG_WARNING("Problem encountered while creating neutral FlowElements");
34 return StatusCode::SUCCESS;
35 }
36 }
37
38 // Record the output containers
39 SG::WriteHandle<xAOD::FlowElementContainer> neutralFEContainerWriteHandle(
41 std::sort(neutralFEContainer->begin(),
42 neutralFEContainer->end(),
43 [](const xAOD::FlowElement* fe1, const xAOD::FlowElement* fe2) {
44 return fe1->pt() > fe2->pt();
45 });
46 ATH_CHECK(neutralFEContainerWriteHandle.record(
47 std::move(neutralFEContainer), std::move(neutralFEContainerAux)));
48
49 return StatusCode::SUCCESS;
50}
51
52StatusCode
54 const eflowCaloObject& energyFlowCaloObject,
55 xAOD::FlowElementContainer* neutralFEContainer) const
56{
57
58 for (unsigned int iCluster = 0; iCluster < energyFlowCaloObject.nClusters(); ++iCluster){
59 const eflowRecCluster* thisEfRecCluster = energyFlowCaloObject.efRecCluster(iCluster);
60
61 /* Skip empty clusters (presumably subtraction remnants) */
62 const CaloClusterCellLink* theCellLink = energyFlowCaloObject.efRecCluster(iCluster)->getCluster()->getCellLinks();
64 CaloClusterCellLink::const_iterator it_e=theCellLink->end();
65 if (it == it_e) {
66 continue;
67 }
68 //this vetoes rare examples where only two cells are left, and they have equal and opposite energy
69 if (0.0 == energyFlowCaloObject.efRecCluster(iCluster)->getCluster()->e() ) continue;
70
71 /* Create the FlowElement, add the cluster and set the four-momentum, charge and type */
72
73 ATH_MSG_VERBOSE("Creating FlowElement");
75 neutralFEContainer->push_back(thisFE);
76
77 ATH_MSG_VERBOSE("Get original cluster link");
78
79 //if we are using the CP data, we want to use the modified cluster link,
80 //given by getClusElementLink and not the non-modified cluster link
81 //given by getOriginalClusElementLink
82 ElementLink<xAOD::CaloClusterContainer> theOriginalClusterLink;
83 if (m_addCPData) theOriginalClusterLink = thisEfRecCluster->getClusElementLink();
84 else theOriginalClusterLink = thisEfRecCluster->getOriginalClusElementLink();
85
86 ATH_MSG_VERBOSE("Cluster link valid? "<<theOriginalClusterLink.isValid()<<"");
87 ATH_MSG_VERBOSE("Get sister cluster link");
88 ElementLink<xAOD::CaloClusterContainer> theSisterClusterLink = (*theOriginalClusterLink)->getSisterClusterLink();
89 ATH_MSG_VERBOSE("Sister cluster link valid? "<<theSisterClusterLink.isValid()<<"");
90
91 std::vector<ElementLink<xAOD::IParticleContainer>> theClusters;
92 if (theSisterClusterLink.isValid() && !m_addCPData){
93 theClusters.emplace_back(theSisterClusterLink);
94 }
95 else{
96 theClusters.emplace_back(theOriginalClusterLink);
97 }
98 thisFE->setOtherObjectLinks(theClusters);
99
100 const static SG::AuxElement::Accessor<
102 accShowerSubtractedClusterLink("FEShowerSubtractedClusterLink");
103 accShowerSubtractedClusterLink(*thisFE) =
104 thisEfRecCluster->getClusElementLink();
105
106 ATH_MSG_VERBOSE(" Sucessfully set cluster link");
107
108 const xAOD::CaloCluster* cluster = thisEfRecCluster->getCluster();
109 ATH_MSG_VERBOSE("Got CaloCluster from EfRecCluster");
110 // be careful here - cluster p4 methods do not store sign. Thus -ve energy
111 // clusters have +ve pt and hence +ve energy we use eta,phi at EM scale for
112 // both 4-vectors - standard FE are at EM scale
113 thisFE->setP4(cluster->rawE() / cosh(cluster->rawEta()),
114 cluster->rawEta(),
115 cluster->rawPhi(),
116 cluster->rawM());
117
118 ATH_MSG_DEBUG("Created neutral FlowElement with E, pt, eta and phi of "
119 << thisFE->e() << ", " << thisFE->pt() << ", "
120 << thisFE->eta() << " and " << thisFE->phi());
121
122 thisFE->setCharge(0);
124
126 FEFiller.addStandardMoments(*thisFE,*cluster);
127
128 if (m_useCalibHitTruth) FEFiller.addStandardCalHitMoments(*thisFE,*cluster);
129
130 FEFiller.addStandardSamplingEnergies(*thisFE,*cluster);
131
132 float layerEnergy_TileBar0 = cluster->eSample(xAOD::CaloCluster::CaloSample::TileBar0);
133 float layerEnergy_TileExt0 = cluster->eSample(xAOD::CaloCluster::CaloSample::TileExt0);
134 const static SG::AuxElement::Accessor<float> accFloatTIle0E("LAYERENERGY_TILE0");
135 accFloatTIle0E(*thisFE) = layerEnergy_TileBar0 + layerEnergy_TileExt0;
136
137 const static SG::AuxElement::Accessor<float> accFloatTiming("TIMING");
138 accFloatTiming(*thisFE) = cluster->time();
139
140 if (m_addCPData){
141 PFClusterWidthCalculator widthCalc;
142 const CaloClusterCellLink* theCellLinks = cluster->getCellLinks();
143 std::vector<double> eta,phi;
144 for (CaloClusterCellLink::const_iterator it=theCellLinks->begin(); it!=theCellLinks->end(); ++it){
145 const CaloCell* cell = *it;
146 eta.push_back(cell->eta());
147 phi.push_back(cell->phi());
148 }
149
150 std::pair<double,double> width = widthCalc.getPFClusterCoordinateWidth(eta,phi,cluster->eta(),cluster->phi(),theCellLinks->size());
151 const static SG::AuxElement::Accessor<float> accFloatWidthEta("ClusterWidthEta");
152 accFloatWidthEta(*thisFE) = width.first;
153 const static SG::AuxElement::Accessor<float> accFloatWidthPhi("ClusterWidthPhi");
154 accFloatWidthPhi(*thisFE) = width.second;
155 }
156
157 }//cluster loop
158 return StatusCode::SUCCESS;
159}
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)
const double width
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
value_type push_back(value_type pElem)
Add an element to the end of the collection.
void addStandardSamplingEnergies(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
void addStandardCalHitMoments(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
void addStandardMoments(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
std::pair< double, double > getPFClusterCoordinateWidth(const std::vector< double > &eta, const std::vector< double > &phi, const double &clusterEta, const double &clusterPhi, unsigned int nCells)
StatusCode createNeutralFlowElement(const eflowCaloObject &energyFlowCaloObject, xAOD::FlowElementContainer *neutralFEContainer) const
Create the chargedneutral FE.
Gaudi::Property< bool > m_addCPData
Toggle whether to decorate FlowElements with addutional data for Combined Performance studies.
SG::WriteHandleKey< xAOD::FlowElementContainer > m_neutralFEContainerWriteHandleKey
WriteHandleKey for neutral FE.
SG::ReadHandleKey< eflowCaloObjectContainer > m_eflowCaloObjectContainerReadHandleKey
ReadHandleKey for eflowCaloObjectContainer.
StatusCode execute(const EventContext &ctx) const
Gaudi::Property< bool > m_useCalibHitTruth
Toggle usage of calibration hit truth - false by default.
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
An internal EDM object which stores information about systems of associated tracks and calorimeter cl...
unsigned nClusters() const
const eflowRecCluster * efRecCluster(int i) const
This class extends the information about a xAOD::CaloCluster.
ElementLink< xAOD::CaloClusterContainer > getOriginalClusElementLink() const
xAOD::CaloCluster * getCluster()
ElementLink< xAOD::CaloClusterContainer > getClusElementLink() const
flt_t rawE() const
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
flt_t rawM() const
Get mass in signal state UNCALIBRATED.
flt_t time() const
Access cluster time.
virtual double eta() const
The pseudorapidity ( ) of the particle.
flt_t rawPhi() const
Get in signal state UNCALIBRATED.
flt_t rawEta() const
Get in signal state UNCALIBRATED.
virtual double e() const
The total energy of the particle.
float eSample(const CaloSample sampling) const
virtual double phi() const
The azimuthal angle ( ) of the particle.
virtual double pt() const override
void setP4(float pt, float eta, float phi, float m)
virtual double phi() const override
The azimuthal angle ( ) of the particle.
void setCharge(float c)
virtual double eta() const override
The pseudorapidity ( ) of the particle.
void setSignalType(signal_t t)
void setOtherObjectLinks(const std::vector< ElementLink< IParticleContainer > > &elV)
virtual double e() const override
The total energy of the particle.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
FlowElementContainer_v1 FlowElementContainer
Definition of the current "pfo container version".
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