not all muons have a track. catch the nullptrs in this case and skip
61 {
62
63
64
66
67
69 ctx);
71 ctx);
72
74 ctx);
76 ctx);
77
78
79
80 SG::WriteDecorHandle<xAOD::FlowElementContainer, std::vector<double>> NeutralFE_efrac_match_muonWriteDecorHandle(
82 SG::WriteDecorHandle<xAOD::MuonContainer, std::vector<double>> muonNeutralFE_muon_efrac_WriteDecorHandle(
84 SG::WriteDecorHandle<xAOD::FlowElementContainer, int> NeutralFEmuon_nMatches_WriteDecorHandle(
86 SG::WriteDecorHandle<xAOD::MuonContainer, double> muon_ClusterInfo_deltaR_WriteDecorHandle(
88
89
93 SG::ReadDecorHandle<xAOD::CaloClusterContainer, std::vector<ElementLink<xAOD::CaloClusterContainer>>> acc_constClusterLinks(
m_ClustCollectionLinkKey,ctx);
94
95 std::vector<std::vector<FlowElementLink_t>> muonChargedFEVec(muonReadHandle->size());
96 std::vector<std::vector<FlowElementLink_t>> muonNeutralFEVec(muonReadHandle->size());
97
98
99 std::vector<std::vector<double>> muonNeutralFE_frac_cluster_energy_matched_Vec(muonReadHandle->size());
100
102
103
104
106
109
110 size_t FETrackIndex = FE->chargedObjects().at(0)->index();
111
112 std::vector<MuonLink_t> FEMuonLinks;
113
114
115 std::vector<double> FEMatchedClusterCellEnergies;
116 for (
unsigned int counter = 0;
counter < FE->otherObjects().
size(); ++
counter) FEMatchedClusterCellEnergies.push_back(0.0);
117
118
119 for (
const xAOD::Muon* muon : *muonChargedFEWriteDecorHandle) {
120 const xAOD::TrackParticle* muon_trk =
muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
122 if (!muon_trk) continue;
123
124 if (
muon->muonType() == xAOD::Muon::MuonType::SiliconAssociatedForwardMuon) {
125
126
127
128 ATH_MSG_DEBUG(
"Muon is identified as a forward muon, skipping");
129 continue;
130 }
131 if (
muon->author() == xAOD::Muon::Author::STACO) {
133 continue;
134 }
135 size_t MuonTrkIndex = muon_trk->index();
136 if (MuonTrkIndex == FETrackIndex) {
137
138
139 FEMuonLinks.emplace_back(*muonReadHandle,
muon->index());
140
141
142 muonChargedFEVec.at(
muon->index()).emplace_back(*ChargedFEReadHandle, FE->index());
143 }
144
145
146
147
150
151 if (!muonCluster) continue;
153 for (auto thisCluster : FE->otherObjects()){
155 bool isCellMatched = false;
156 std::pair <double,double> FEAndMuonMatchedCellEnergy = this->
doMuonCellMatching(isCellMatched, *thisCaloCluster,*muonCluster);
157 FEMatchedClusterCellEnergies[
counter] += FEAndMuonMatchedCellEnergy.first;
159 }
160 }
161 }
162
163 chargedFE_energy_match_muonWriteHandle(*FE) = FEMatchedClusterCellEnergies;
164
165
166 ChargedFEmuonWriteDecorHandle(*FE) = FEMuonLinks;
167 }
168
170
172
182 ATH_MSG_VERBOSE(
"Experimental: Cluster Linkers between neutral FEs and Muons are used");
184 int nMatchedFE = 0;
185
187 ATH_MSG_DEBUG(
"FE with e, eta and phi" << FE->e() <<
", " << FE->eta() <<
" and " << FE->phi());
188 const xAOD::IParticle* otherObject = FE->otherObjects().at(0);
189
190
191 if (!otherObject){
192 ATH_MSG_DEBUG(
"No linked cluster for Neutral FE with E, eta and phi" << FE->e() <<
", " << FE->eta() <<
" and " << FE->phi());
193 continue;
194 }
195 size_t FEclusterindex = otherObject->index();
196
197
198 const xAOD::IParticle* FE_Iparticle = FE->otherObjects().at(0);
199
200
202
203
204
205 double cluster_E = FE_cluster->
p4().E();
206 bool neg_E_cluster = (cluster_E < 0.0);
207
208
209 std::vector<MuonLink_t> FEMuonLinks;
210 std::vector<double> FE_efrac_clustermatch;
211 std::vector<double> Muon_efrac_clustermatch;
212 for (
const xAOD::Muon* muon : *muonNeutralFEWriteDecorHandle) {
213
215
216
217 if (!cluster) {
219 continue;
220 }
222
223 const std::vector<ElementLink<xAOD::CaloClusterContainer>>& linksToTopoClusters = acc_constClusterLinks(*cluster);
224 for (const ElementLink<xAOD::CaloClusterContainer>& TopoClusterLink : linksToTopoClusters) {
225
226
227 if (!TopoClusterLink.isValid()) {
228 ATH_MSG_DEBUG(
"Muon Calo cluster's TopoCluster link not found, skip");
229 continue;
230 }
232 size_t MuonTopoCluster_index = MuonTopoCluster->index();
233 if (MuonTopoCluster_index == FEclusterindex) {
234
235
236 FEMuonLinks.emplace_back(*muonReadHandle,
muon->index());
237
238 muonNeutralFEVec.at(
muon->index()).emplace_back(*NeutralFEReadHandle, FE->index());
240 nMatchedFE++;
241 if (neg_E_cluster)
ATH_MSG_ERROR(
"Muon cluster matched to negative E topocluster from FE");
242 }
243 }
244 }
245 else {
246
247
248
249
250 bool isCellMatched = false;
251 std::pair<double,double> FEAndMuonMatchedCellEnergy = this->
doMuonCellMatching(isCellMatched, *FE_cluster,*cluster);
252
253 double FE_sum_matched_cellEnergy = FEAndMuonMatchedCellEnergy.first;
254 double Muon_sum_matched_cellEnergy = FEAndMuonMatchedCellEnergy.second;
255
256 double frac_FE_cluster_energy_matched = 0;
257
258 double tot_FE_cluster_energy = FE_cluster->
e();
259 if (tot_FE_cluster_energy != 0) {
260 frac_FE_cluster_energy_matched = FE_sum_matched_cellEnergy / tot_FE_cluster_energy;
261 }
262 double tot_muon_cluster_energy = cluster->
e();
263 double frac_muon_cluster_energy_matched = 0;
264 if (tot_muon_cluster_energy != 0) {
265 frac_muon_cluster_energy_matched = Muon_sum_matched_cellEnergy / tot_muon_cluster_energy;
266 }
267 if (frac_FE_cluster_energy_matched > 0) {
268 ATH_MSG_VERBOSE(
"Fraction of FE cluster energy used in match: " << frac_FE_cluster_energy_matched <<
", ismatched? "
269 << isCellMatched << "");
270 ATH_MSG_VERBOSE(
"Numerator and denominator are " << FE_sum_matched_cellEnergy <<
" and " << tot_FE_cluster_energy);
271 ATH_MSG_VERBOSE(
"Fraction of Muon cluster energy used in match: " << frac_muon_cluster_energy_matched <<
"");
272 }
273
274 if (isCellMatched) {
275
276
277 FEMuonLinks.emplace_back(*muonReadHandle,
muon->index());
278
279 muonNeutralFEVec.at(
muon->index()).emplace_back(*NeutralFEReadHandle, FE->index());
280
281 FE_efrac_clustermatch.push_back(frac_FE_cluster_energy_matched);
282 muonNeutralFE_frac_cluster_energy_matched_Vec.at(
muon->index())
283 .push_back(frac_muon_cluster_energy_matched);
284 nMatchedFE++;
285 if (neg_E_cluster) {
ATH_MSG_ERROR(
"Muon cluster matched to negative E topocluster from FE"); }
286 }
287
288 }
289
290 }
291 NeutralFEmuon_nMatches_WriteDecorHandle(*FE) = nMatchedFE;
292 NeutralFEmuonWriteDecorHandle(*FE) = FEMuonLinks;
293 NeutralFE_efrac_match_muonWriteDecorHandle(*FE) = FE_efrac_clustermatch;
294 }
295 }
296
298
300
301 for (
const xAOD::Muon* muon : *muonChargedFEWriteDecorHandle) {
302 muonChargedFEWriteDecorHandle(*muon) = muonChargedFEVec.at(
muon->index());
303 }
305 for (
const xAOD::Muon* muon : *muonNeutralFEWriteDecorHandle) {
306 if (!muonNeutralFEVec.empty()) {
307 muonNeutralFEWriteDecorHandle(*muon) = muonNeutralFEVec.at(
muon->index());
308 muonNeutralFE_muon_efrac_WriteDecorHandle(*muon) = muonNeutralFE_frac_cluster_energy_matched_Vec.at(
muon->index());
309 }
310
311
312
314
316 }
317 }
319
320 return StatusCode::SUCCESS;
321}
#define ATH_MSG_VERBOSE(x)
size_t size() const
Number of registered mappings.
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_ChargedFE_energy_match_muonWriteHandleKey
Write key for adding fraction of nFlowElement cluster energy used in cell matching decoration of Flow...
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonNeutralFE_muon_efrac_WriteDecorHandleKey
Write key for adding fraction of Muon cluster energy used in cell matching decoration of MuonContaine...
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_NeutralFEmuon_nMatches_WriteDecorHandleKey
Write key to count number of muons matched to a given neutral FE - EXPERIMENTAL.
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muon_ClusterInfo_deltaR_WriteDecorHandleKey
Write key to measure dR between calo clusters and the muon -EXPERIMENTAL.
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_NeutralFE_efrac_match_muonWriteHandleKey
Write key for adding fraction of nFlowElement cluster energy used in cell matching decoration of Flow...
std::pair< double, double > doMuonCellMatching(bool &isCellMatched, const xAOD::CaloCluster &FECluster, const xAOD::CaloCluster &muonCluster) const
Function that flags whether the FE cluster has any cell that is also in the muon list of cells.
SG::ReadDecorHandleKey< xAOD::CaloClusterContainer > m_ClustCollectionLinkKey
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonNeutralFEWriteHandleKey
Write key for adding neutral Flow Element link decorations to muons.
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_NeutralFEmuonWriteHandleKey
Write key for adding Muon link decorations to neutral Flow Elements.
SG::ReadHandleKey< xAOD::FlowElementContainer > m_neutralFEReadHandleKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_ChargedFEmuonWriteHandleKey
Write key for adding Muon link decorations to charged Flow Elements.
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonChargedFEWriteHandleKey
Write key for adding charged Flow Element link decorations to muons.
SG::ReadHandleKey< xAOD::FlowElementContainer > m_chargedFEReadHandleKey
Gaudi::Property< bool > m_LinkNeutralFEClusters
Gaudi Property to configure linkage of Neutral Flow Elements to Muon clusters (EXPERIMENTAL - default...
SG::ReadHandleKey< xAOD::MuonContainer > m_muonReadHandleKey
virtual double e() const
The total energy of the particle.
virtual FourMom_t p4() const
The full 4-momentum of the particle.
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Muon_v1 Muon
Reference the current persistent version: