Patch for STACO muons: Copy the truth information from the muon back to the combined track to avoid file corruptions reported in ATLASRECTS-6454
one more thing: need to have muonlink set for all truth particles to avoid ELReset errors
92 {
95 std::unique_ptr<SG::WriteDecorHandle<xAOD::TruthParticleContainer, ElementLink<xAOD::MuonContainer>>> muonTruthParticleRecoLink{};
97 muonTruthParticleRecoLink = std::make_unique<SG::WriteDecorHandle<xAOD::TruthParticleContainer, ElementLink<xAOD::MuonContainer>>>(
m_muonTruthRecoLink, ctx);
98 }
99
100 SG::WriteDecorHandle<xAOD::MuonContainer, ElementLink<xAOD::TruthParticleContainer> > muonTruthParticleLink(
m_muonTruthParticleLink,
101 ctx);
102 if (!muonTruthParticleLink.isValid()) {
104 return StatusCode::FAILURE;
105 }
110 ctx);
113
114
115 bool saw_staco = false;
116 bool decor_staco = false;
117
118
119 for (
const xAOD::Muon* muon : *muonTruthParticleLink) {
120
121
126 tp =
muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
127 } else {
128 tp =
muon->primaryTrackParticle();
129 }
130
131 bool foundTruth{false}, setOrigin{false};
132 if (tp) {
133
134
135
136 if (acc_origin.isAvailable(*tp) && acc_origin(*tp) != 0) {
137 muonTruthParticleOrigin(*muon) = acc_origin(*tp);
138 muonTruthParticleType(*muon) = acc_type(*tp);
139 muonTruthParticleClassification(*muon) = acc_classification(*tp);
140 setOrigin = true;
141 }
142
143 ElementLink<xAOD::TruthParticleContainer> truthLink;
144 if (acc_link.isAvailable(*tp)) {
145 truthLink = acc_link(*tp);
146 } else {
147 ATH_MSG_DEBUG(
"Could not find any truth link associated with track having pt:"<<
tp->pt()<<
" MeV, eta: "<<
tp->eta()<<
", phi: "<<
tp->phi()<<
", charge: "<<
tp->charge()<<
". d0:"<<
tp->d0()<<
", z0: "<<
tp->z0());
148 }
149
152
159 continue;
160 }
162 foundTruth = true;
164 ElementLink<xAOD::TruthParticleContainer> muonTruthLink{*muonTruthContainer,
165 truthParticle->index(),
166 ctx};
168 muonTruthParticleLink(*muon) = muonTruthLink;
169 if (!setOrigin) {
170 muonTruthParticleOrigin(*muon) = acc_origin(*tp);
171 muonTruthParticleType(*muon) = acc_type(*tp);
172 muonTruthParticleClassification(*muon) = acc_classification(*tp);
173 setOrigin = true;
174 }
176 if (muonTruthParticleRecoLink && muonTruthParticleRecoLink->operator()(*truthParticle).isValid()){
177 const xAOD::Muon* decor_muon = *muonTruthParticleRecoLink->operator()(*truthParticle);
178 ATH_MSG_VERBOSE(
"Truth particle is already decorated with reco muon "<<decor_muon->
pt()*1.e-3
179 <<
" eta: "<<decor_muon->
eta()<<
" phi: "<<decor_muon->
phi()<<
" charge: "<<
180 decor_muon->
charge()<<
" author: "<<decor_muon->
author()<<
" all authors: "<<
182
183
185 ATH_MSG_DEBUG(
"Author of the decorated muon is better than the one of the new candidate");
186 continue;
187 }
189 const int com_score = (
muon->allAuthors() & com_bit) - (decor_muon->
allAuthors() &com_bit);
190 if (com_score > 0){
191 ATH_MSG_DEBUG(
"Found two muons reconstructed by an equivalent author. But this one is from the commissioning chain");
192 continue;
193 }
195 if (
deltaR2(muon,truthParticle) >=
deltaR2(muon, decor_muon))
continue;
196 }
197
198
199 ElementLink<xAOD::MuonContainer> muonLink{
muon, *muonTruthParticleLink, ctx};
200
202 std::vector<unsigned int> nprecHitsPerChamberLayer(
toInt(ChIndex::ChIndexMax), dummy_unsigned);
203 std::vector<unsigned int> nphiHitsPerChamberLayer(
toInt(PhiIndex::PhiIndexMax), dummy_unsigned);
204 std::vector<unsigned int> ntrigEtaHitsPerChamberLayer(
toInt(PhiIndex::PhiIndexMax), dummy_unsigned);
205
206 constexpr int author_sel = (1<<xAOD::Muon::MuidCo) | (1<<xAOD::Muon::MuidSA) | (1<<xAOD::Muon::MuGirl);
208 ? truthParticle
209 : nullptr,
210 tp->track(), nprecHitsPerChamberLayer, nphiHitsPerChamberLayer, ntrigEtaHitsPerChamberLayer);
212 muonTruthParticleNPrecMatched(*muon) = nprecHitsPerChamberLayer;
213 muonTruthParticleNPhiMatched(*muon) = nphiHitsPerChamberLayer;
214 muonTruthParticleNTrigEtaMatched(*muon) = ntrigEtaHitsPerChamberLayer;
215
216 if (muonTruthParticleRecoLink) (*muonTruthParticleRecoLink)(*truthParticle) = muonLink;
217 break;
218 }
219 } else {
221 }
222 } else {
223 ATH_MSG_WARNING(
"Could not find the appropiate track particle for muon with pT: " <<
muon->pt() * 1.e-3 <<
" GeV, eta: "
224 <<
muon->eta() <<
", phi: " <<
muon->phi()
225 <<
" author: " <<
muon->author());
226 }
227
228 if (!setOrigin) {
229 muonTruthParticleOrigin(*muon) = 0;
230 muonTruthParticleType(*muon) = 0;
231 muonTruthParticleClassification(*muon) = 0;
232 }
233 if (!foundTruth) {
234 muonTruthParticleLink(*muon) = ElementLink<xAOD::TruthParticleContainer>();
235
236 muonTruthParticleNPrecMatched(*muon) = std::vector<unsigned int>{};
237 muonTruthParticleNPhiMatched(*muon) = std::vector<unsigned int>{};
238 muonTruthParticleNTrigEtaMatched(*muon) = std::vector<unsigned int>{};
239 }
242 if (
muon->author() == xAOD::Muon::STACO) {
244 if (!cmb_trk){
246 continue;
247 } else {
248 if (!saw_staco) {
249 saw_staco = true;
250 decor_staco = !dec_origin.isAvailable (*cmb_trk);
251 }
252 if (decor_staco) {
253 dec_origin(*cmb_trk) = acc_origin(*muon);
254 dec_classification(*cmb_trk) = acc_classification(*muon);
255 dec_type(*cmb_trk) = acc_type(*muon);
256 dec_link(*cmb_trk) = acc_link(*muon);
257 }
258 }
259 }
260 }
262 if (muonTruthParticleRecoLink && !muonTruthParticleRecoLink->isAvailable()) {
265 (*muonTruthParticleRecoLink)(*truthParticle) = ElementLink<xAOD::MuonContainer>();
266 }
267 }
268
269 return StatusCode::SUCCESS;
270}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool toPersistent()
Dummy function provinding the offline interface.
bool isValid() const
Test to see if the link can be dereferenced.
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonTruthParticleOrigin
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonTruthParticleNPhiMatched
Gaudi::Property< bool > m_associateWithInDetTP
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_muonTruthRecoLink
Decorations for the filtered muon truth particles.
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonTruthParticleClassification
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonTruthParticleType
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonTruthParticleLink
Decorations for the reconstructed muon particles.
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonTruthParticleNTrigEtaMatched
void count_chamber_layers(const xAOD::IParticle *truth_particle, const Trk::Track *ptrk, std::vector< unsigned int > &nprecHitsPerChamberLayer, std::vector< unsigned int > &nphiHitsPerChamberLayer, std::vector< unsigned int > &ntrigEtaHitsPerChamberLayer) const
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthMuKey
Key to the filtered muon truth particles.
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonTruthParticleNPrecMatched
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
virtual double pt() const
The transverse momentum ( ) of the particle.
uint16_t allAuthors() const
Get all the authors of this Muon.
bool is_sim_descendant(const T1 &p1, const T2 &p2)
Method to check if the first particle is a descendant of the second in the simulation,...
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
int authorRank(const xAOD::Muon::Author &a)
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
double deltaR2(double rapidity1, double phi1, double rapidity2, double phi2)
from bare rapidity,phi
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TruthParticle_v1 TruthParticle
Typedef to implementation.
Muon_v1 Muon
Reference the current persistent version:
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.