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 int MuonType =
muon->muonType();
125 int MuonAuthor =
muon->author();
126 if (MuonType == xAOD::Muon::SiliconAssociatedForwardMuon) {
127
128
129
130 ATH_MSG_DEBUG(
"Muon is identified as a forward muon, skipping");
131 continue;
132 }
133 if (MuonAuthor == xAOD::Muon::Author::STACO) {
135 continue;
136 }
137 size_t MuonTrkIndex = muon_trk->
index();
138 if (MuonTrkIndex == FETrackIndex) {
139
140
141 FEMuonLinks.emplace_back(*muonReadHandle,
muon->index());
142
143
144 muonChargedFEVec.at(
muon->index()).emplace_back(*ChargedFEReadHandle, FE->index());
145 }
146
147
148
149
152
153 if (!muonCluster) continue;
155 for (auto thisCluster : FE->otherObjects()){
157 bool isCellMatched = false;
158 std::pair <double,double> FEAndMuonMatchedCellEnergy = this->
doMuonCellMatching(isCellMatched, *thisCaloCluster,*muonCluster);
159 FEMatchedClusterCellEnergies[
counter] += FEAndMuonMatchedCellEnergy.first;
161 }
162 }
163 }
164
165 chargedFE_energy_match_muonWriteHandle(*FE) = FEMatchedClusterCellEnergies;
166
167
168 ChargedFEmuonWriteDecorHandle(*FE) = FEMuonLinks;
169 }
170
172
174
184 ATH_MSG_VERBOSE(
"Experimental: Cluster Linkers between neutral FEs and Muons are used");
186 int nMatchedFE = 0;
187
189 ATH_MSG_DEBUG(
"FE with e, eta and phi" << FE->e() <<
", " << FE->eta() <<
" and " << FE->phi());
190 const xAOD::IParticle* otherObject = FE->otherObjects().at(0);
191
192
193 if (!otherObject){
194 ATH_MSG_DEBUG(
"No linked cluster for Neutral FE with E, eta and phi" << FE->e() <<
", " << FE->eta() <<
" and " << FE->phi());
195 continue;
196 }
197 size_t FEclusterindex = otherObject->
index();
198
199
200 const xAOD::IParticle* FE_Iparticle = FE->otherObjects().at(0);
201
202
204
205
206
207 double cluster_E = FE_cluster->
p4().E();
208 bool neg_E_cluster = (cluster_E < 0.0);
209
210
211 std::vector<MuonLink_t> FEMuonLinks;
212 std::vector<double> FE_efrac_clustermatch;
213 std::vector<double> Muon_efrac_clustermatch;
214 for (
const xAOD::Muon* muon : *muonNeutralFEWriteDecorHandle) {
215
217
218
219 if (!cluster) {
221 continue;
222 }
224
225 const std::vector<ElementLink<xAOD::CaloClusterContainer>>& linksToTopoClusters = acc_constClusterLinks(*cluster);
226 for (const ElementLink<xAOD::CaloClusterContainer>& TopoClusterLink : linksToTopoClusters) {
227
228
229 if (!TopoClusterLink.isValid()) {
230 ATH_MSG_DEBUG(
"Muon Calo cluster's TopoCluster link not found, skip");
231 continue;
232 }
234 size_t MuonTopoCluster_index = MuonTopoCluster->
index();
235 if (MuonTopoCluster_index == FEclusterindex) {
236
237
238 FEMuonLinks.emplace_back(*muonReadHandle,
muon->index());
239
240 muonNeutralFEVec.at(
muon->index()).emplace_back(*NeutralFEReadHandle, FE->index());
242 nMatchedFE++;
243 if (neg_E_cluster)
ATH_MSG_ERROR(
"Muon cluster matched to negative E topocluster from FE");
244 }
245 }
246 }
247 else {
248
249
250
251
252 bool isCellMatched = false;
253 std::pair<double,double> FEAndMuonMatchedCellEnergy = this->
doMuonCellMatching(isCellMatched, *FE_cluster,*cluster);
254
255 double FE_sum_matched_cellEnergy = FEAndMuonMatchedCellEnergy.first;
256 double Muon_sum_matched_cellEnergy = FEAndMuonMatchedCellEnergy.second;
257
258 double frac_FE_cluster_energy_matched = 0;
259
260 double tot_FE_cluster_energy = FE_cluster->
e();
261 if (tot_FE_cluster_energy != 0) {
262 frac_FE_cluster_energy_matched = FE_sum_matched_cellEnergy / tot_FE_cluster_energy;
263 }
264 double tot_muon_cluster_energy = cluster->
e();
265 double frac_muon_cluster_energy_matched = 0;
266 if (tot_muon_cluster_energy != 0) {
267 frac_muon_cluster_energy_matched = Muon_sum_matched_cellEnergy / tot_muon_cluster_energy;
268 }
269 if (frac_FE_cluster_energy_matched > 0) {
270 ATH_MSG_VERBOSE(
"Fraction of FE cluster energy used in match: " << frac_FE_cluster_energy_matched <<
", ismatched? "
271 << isCellMatched << "");
272 ATH_MSG_VERBOSE(
"Numerator and denominator are " << FE_sum_matched_cellEnergy <<
" and " << tot_FE_cluster_energy);
273 ATH_MSG_VERBOSE(
"Fraction of Muon cluster energy used in match: " << frac_muon_cluster_energy_matched <<
"");
274 }
275
276 if (isCellMatched) {
277
278
279 FEMuonLinks.emplace_back(*muonReadHandle,
muon->index());
280
281 muonNeutralFEVec.at(
muon->index()).emplace_back(*NeutralFEReadHandle, FE->index());
282
283 FE_efrac_clustermatch.push_back(frac_FE_cluster_energy_matched);
284 muonNeutralFE_frac_cluster_energy_matched_Vec.at(
muon->index())
285 .push_back(frac_muon_cluster_energy_matched);
286 nMatchedFE++;
287 if (neg_E_cluster) {
ATH_MSG_ERROR(
"Muon cluster matched to negative E topocluster from FE"); }
288 }
289
290 }
291
292 }
293 NeutralFEmuon_nMatches_WriteDecorHandle(*FE) = nMatchedFE;
294 NeutralFEmuonWriteDecorHandle(*FE) = FEMuonLinks;
295 NeutralFE_efrac_match_muonWriteDecorHandle(*FE) = FE_efrac_clustermatch;
296 }
297 }
298
300
302
303 for (
const xAOD::Muon* muon : *muonChargedFEWriteDecorHandle) {
304 muonChargedFEWriteDecorHandle(*muon) = muonChargedFEVec.at(
muon->index());
305 }
307 for (
const xAOD::Muon* muon : *muonNeutralFEWriteDecorHandle) {
308 if (!muonNeutralFEVec.empty()) {
309 muonNeutralFEWriteDecorHandle(*muon) = muonNeutralFEVec.at(
muon->index());
310 muonNeutralFE_muon_efrac_WriteDecorHandle(*muon) = muonNeutralFE_frac_cluster_energy_matched_Vec.at(
muon->index());
311 }
312
313
314
316
318 }
319 }
321
322 return StatusCode::SUCCESS;
323}
#define ATH_MSG_VERBOSE(x)
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
size_t index() const
Return the index of this element within its container.
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: