95 std::vector<std::vector<FlowElementLink_t>> muonChargedFEVec(muonReadHandle->size());
96 std::vector<std::vector<FlowElementLink_t>> muonNeutralFEVec(muonReadHandle->size());
99 std::vector<std::vector<double>> muonNeutralFE_frac_cluster_energy_matched_Vec(muonReadHandle->size());
110 size_t FETrackIndex = FE->chargedObjects().at(0)->index();
112 std::vector<MuonLink_t> FEMuonLinks;
115 std::vector<double> FEMatchedClusterCellEnergies;
116 for (
unsigned int counter = 0; counter < FE->otherObjects().
size(); ++counter) FEMatchedClusterCellEnergies.push_back(0.0);
119 for (
const xAOD::Muon* muon : *muonChargedFEWriteDecorHandle) {
120 const xAOD::TrackParticle* muon_trk = muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
122 if (!muon_trk)
continue;
124 if (muon->muonType() == xAOD::Muon::MuonType::SiliconAssociatedForwardMuon) {
128 ATH_MSG_DEBUG(
"Muon is identified as a forward muon, skipping");
131 if (muon->author() == xAOD::Muon::Author::STACO) {
135 size_t MuonTrkIndex = muon_trk->index();
136 if (MuonTrkIndex == FETrackIndex) {
139 FEMuonLinks.emplace_back(*muonReadHandle, muon->index());
142 muonChargedFEVec.at(muon->index()).emplace_back(*ChargedFEReadHandle, FE->index());
151 if (!muonCluster)
continue;
152 unsigned int counter = 0;
153 for (
auto thisCluster : FE->otherObjects()){
155 if (!thisCaloCluster)[[
unlikely]]
continue;
156 bool isCellMatched =
false;
157 std::pair <double,double> FEAndMuonMatchedCellEnergy = this->
doMuonCellMatching(isCellMatched, *thisCaloCluster,*muonCluster);
158 FEMatchedClusterCellEnergies[counter] += FEAndMuonMatchedCellEnergy.first;
164 chargedFE_energy_match_muonWriteHandle(*FE) = std::move(FEMatchedClusterCellEnergies);
167 ChargedFEmuonWriteDecorHandle(*FE) = std::move(FEMuonLinks);
183 ATH_MSG_VERBOSE(
"Experimental: Cluster Linkers between neutral FEs and Muons are used");
188 ATH_MSG_DEBUG(
"FE with e, eta and phi" << FE->e() <<
", " << FE->eta() <<
" and " << FE->phi());
193 ATH_MSG_DEBUG(
"No linked cluster for Neutral FE with E, eta and phi" << FE->e() <<
", " << FE->eta() <<
" and " << FE->phi());
196 size_t FEclusterindex = otherObject->index();
203 if (!FE_cluster) [[
unlikely]]
continue;
206 double cluster_E = FE_cluster->
p4().E();
207 bool neg_E_cluster = (cluster_E < 0.0);
210 std::vector<MuonLink_t> FEMuonLinks;
211 std::vector<double> FE_efrac_clustermatch;
212 std::vector<double> Muon_efrac_clustermatch;
213 for (
const xAOD::Muon* muon : *muonNeutralFEWriteDecorHandle) {
224 const std::vector<ElementLink<xAOD::CaloClusterContainer>>& linksToTopoClusters = acc_constClusterLinks(*cluster);
228 if (!TopoClusterLink.isValid()) {
229 ATH_MSG_DEBUG(
"Muon Calo cluster's TopoCluster link not found, skip");
233 size_t MuonTopoCluster_index = MuonTopoCluster->index();
234 if (MuonTopoCluster_index == FEclusterindex) {
237 FEMuonLinks.emplace_back(*muonReadHandle, muon->index());
239 muonNeutralFEVec.at(muon->index()).emplace_back(*NeutralFEReadHandle, FE->index());
242 if (neg_E_cluster)
ATH_MSG_ERROR(
"Muon cluster matched to negative E topocluster from FE");
251 bool isCellMatched =
false;
252 std::pair<double,double> FEAndMuonMatchedCellEnergy = this->
doMuonCellMatching(isCellMatched, *FE_cluster,*cluster);
254 double FE_sum_matched_cellEnergy = FEAndMuonMatchedCellEnergy.first;
255 double Muon_sum_matched_cellEnergy = FEAndMuonMatchedCellEnergy.second;
257 double frac_FE_cluster_energy_matched = 0;
259 double tot_FE_cluster_energy = FE_cluster->
e();
260 if (tot_FE_cluster_energy != 0) {
261 frac_FE_cluster_energy_matched = FE_sum_matched_cellEnergy / tot_FE_cluster_energy;
263 double tot_muon_cluster_energy = cluster->
e();
264 double frac_muon_cluster_energy_matched = 0;
265 if (tot_muon_cluster_energy != 0) {
266 frac_muon_cluster_energy_matched = Muon_sum_matched_cellEnergy / tot_muon_cluster_energy;
268 if (frac_FE_cluster_energy_matched > 0) {
269 ATH_MSG_VERBOSE(
"Fraction of FE cluster energy used in match: " << frac_FE_cluster_energy_matched <<
", ismatched? "
270 << isCellMatched <<
"");
271 ATH_MSG_VERBOSE(
"Numerator and denominator are " << FE_sum_matched_cellEnergy <<
" and " << tot_FE_cluster_energy);
272 ATH_MSG_VERBOSE(
"Fraction of Muon cluster energy used in match: " << frac_muon_cluster_energy_matched <<
"");
278 FEMuonLinks.emplace_back(*muonReadHandle, muon->index());
280 muonNeutralFEVec.at(muon->index()).emplace_back(*NeutralFEReadHandle, FE->index());
282 FE_efrac_clustermatch.push_back(frac_FE_cluster_energy_matched);
283 muonNeutralFE_frac_cluster_energy_matched_Vec.at(muon->index())
284 .push_back(frac_muon_cluster_energy_matched);
286 if (neg_E_cluster) {
ATH_MSG_ERROR(
"Muon cluster matched to negative E topocluster from FE"); }
292 NeutralFEmuon_nMatches_WriteDecorHandle(*FE) = nMatchedFE;
293 NeutralFEmuonWriteDecorHandle(*FE) = std::move(FEMuonLinks);
294 NeutralFE_efrac_match_muonWriteDecorHandle(*FE) = std::move(FE_efrac_clustermatch);
302 for (
const xAOD::Muon* muon : *muonChargedFEWriteDecorHandle) {
303 muonChargedFEWriteDecorHandle(*muon) = muonChargedFEVec.at(muon->index());
306 for (
const xAOD::Muon* muon : *muonNeutralFEWriteDecorHandle) {
307 if (!muonNeutralFEVec.empty()) {
308 muonNeutralFEWriteDecorHandle(*muon) = muonNeutralFEVec.at(muon->index());
309 muonNeutralFE_muon_efrac_WriteDecorHandle(*muon) = muonNeutralFE_frac_cluster_energy_matched_Vec.at(muon->index());
321 return StatusCode::SUCCESS;