Belle II Software development
CDCMCHitCollectionLookUp.icc.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <tracking/trackFindingCDC/mclookup/CDCMCHitCollectionLookUp.h>
11
12#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory3D.h>
13
14#include <tracking/trackingUtilities/utilities/ReversedRange.h>
15#include <tracking/trackingUtilities/utilities/Functional.h>
16
17#include <cdc/dataobjects/CDCHit.h>
18#include <cdc/dataobjects/CDCSimHit.h>
19#include <mdst/dataobjects/MCParticle.h>
20
21#include <TDatabasePDG.h>
22
23namespace Belle2 {
28 namespace TrackFindingCDC {
29
30 template <class ACDCHitCollection>
32 {
33 B2DEBUG(25, "Clearing CDCMCHitCollectionLookUp<ACDCHitCollection>");
34 }
35
36 template <class ACDCHitCollection>
37 std::map<ITrackType, size_t>
39 const ACDCHitCollection& hits) const
40 {
41 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
42
43 std::map<ITrackType, size_t> hitCountByMCTrackId;
44 for (const CDCHit* ptrHit : hits) {
45 ITrackType mcTrackId = mcHitLookUp.getMCTrackId(ptrHit);
46 // cppcheck-suppress stlFindInsert
47 if (hitCountByMCTrackId.count(mcTrackId) == 0) hitCountByMCTrackId[mcTrackId] = 0;
48 ++(hitCountByMCTrackId[mcTrackId]);
49 }
50 return hitCountByMCTrackId;
51 }
52
53 template <class ACDCHitCollection>
55 const ACDCHitCollection& hits) const
56 {
57 std::map<ITrackType, size_t> hitCountByMCTrackId = getHitCountByMCTrackId(hits);
58
59 size_t nHits = 0;
60 std::pair<ITrackType, size_t> highestHitCountMCTrackId(0, 0);
61 static_cast<void>(std::max_element(hitCountByMCTrackId.begin(), hitCountByMCTrackId.end(),
62 TrackingUtilities::LessOf<TrackingUtilities::Second>()));
63
64 for (const auto& hitCountForMCTrackId : hitCountByMCTrackId) {
65
66 nHits += hitCountForMCTrackId.second;
67
68 if (highestHitCountMCTrackId.second < hitCountForMCTrackId.second) {
69 highestHitCountMCTrackId = hitCountForMCTrackId;
70 }
71 }
72
73 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
74
75 int correctRLVote = 0;
76 for (const auto& recoHit : hits) {
77 const CDCHit* hit = recoHit;
78 TrackingUtilities::ERightLeft mcRLInfo = mcHitLookUp.getRLInfo(hit);
79 TrackingUtilities::ERightLeft rlInfo = recoHit.getRLInfo();
80 if (rlInfo == mcRLInfo) {
81 ++correctRLVote;
82 } else {
83 --correctRLVote;
84 }
85 }
86
87 const float purity = static_cast<float>(highestHitCountMCTrackId.second) / nHits;
88 return MCTrackIdPurityPair(highestHitCountMCTrackId.first, purity, correctRLVote);
89 }
90
91 template <class ACDCHitCollection>
92 ITrackType
93 CDCMCHitCollectionLookUp<ACDCHitCollection>::getMCTrackId(const ACDCHitCollection* ptrHits) const
94 {
95 if (not ptrHits) return INVALID_ITRACK;
96 const ACDCHitCollection& hits = *ptrHits;
97 MCTrackIdPurityPair mcTrackIdAndPurity = getHighestPurity(hits);
98 if (mcTrackIdAndPurity.getPurity() >= m_minimalMatchPurity) {
99 return mcTrackIdAndPurity.getMCTrackId();
100 } else {
101 return INVALID_ITRACK;
102 }
103 }
105 template <class ACDCHitCollection>
107 const ACDCHitCollection* ptrHits) const
109 if (not ptrHits) return INVALID_ITRACK;
110 const ACDCHitCollection& hits = *ptrHits;
111 MCTrackIdPurityPair mcTrackIdAndPurity = getHighestPurity(hits);
112 if (mcTrackIdAndPurity.getPurity() >= m_minimalMatchPurity) {
113 return mcTrackIdAndPurity.getCorrectRLVote();
114 } else {
115 return 0;
116 }
117 }
118
119 template <class ACDCHitCollection>
120 double
121 CDCMCHitCollectionLookUp<ACDCHitCollection>::getRLPurity(const ACDCHitCollection* ptrHits) const
122 {
123 TrackingUtilities::EForwardBackward fbInfo = isForwardOrBackwardToMCTrack(ptrHits);
124 if (fbInfo == TrackingUtilities::EForwardBackward::c_Invalid) return NAN;
125
126 int correctRLVote = getCorrectRLVote(ptrHits);
127
128 if (fbInfo == TrackingUtilities::EForwardBackward::c_Backward) {
129 correctRLVote = -correctRLVote;
130 }
131
132 int nCorrectRL = (correctRLVote + ptrHits->size()) / 2;
133 float rlPurity = 1.0 * nCorrectRL / ptrHits->size();
134 return rlPurity;
135 }
136
137 template <class ACDCHitCollection>
139 const ACDCHitCollection* ptrHits) const
140 {
141 const CDCHit* ptrHit = getFirstHit(ptrHits);
142 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
143 return mcHitLookUp.getMCParticle(ptrHit);
144 }
145
146 template <class ACDCHitCollection>
147 const CDCHit*
148 CDCMCHitCollectionLookUp<ACDCHitCollection>::getFirstHit(const ACDCHitCollection* ptrHits) const
149 {
150 if (not ptrHits) return nullptr;
151 const ACDCHitCollection& hits = *ptrHits;
152
153 ITrackType mcTrackId = getMCTrackId(ptrHits);
154 if (mcTrackId == INVALID_ITRACK) return nullptr;
155
156 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
157
158 for (const CDCHit* hit : hits) {
159 if (mcTrackId == mcHitLookUp.getMCTrackId(hit)) return hit;
160 }
161 return nullptr;
162 }
163
164 template <class ACDCHitCollection>
165 const CDCHit*
166 CDCMCHitCollectionLookUp<ACDCHitCollection>::getLastHit(const ACDCHitCollection* ptrHits) const
167 {
168
169 if (not ptrHits) return nullptr;
170 const ACDCHitCollection& hits = *ptrHits;
172 ITrackType mcTrackId = getMCTrackId(ptrHits);
173 if (mcTrackId == INVALID_ITRACK) return nullptr;
174
175 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
176
177 for (const CDCHit* hit : TrackingUtilities::reversedRange(hits)) {
178 if (mcTrackId == mcHitLookUp.getMCTrackId(hit)) return hit;
180 return nullptr;
181 }
182
183 template <class ACDCHitCollection>
185 const ACDCHitCollection* ptrHits) const
186 {
187 TrackingUtilities::Index firstInTrackId = getFirstInTrackId(ptrHits);
188 TrackingUtilities::Index lastInTrackId = getLastInTrackId(ptrHits);
189 if (firstInTrackId == TrackingUtilities::c_InvalidIndex or lastInTrackId == TrackingUtilities::c_InvalidIndex) {
190 return TrackingUtilities::EForwardBackward::c_Invalid;
191 } else if (firstInTrackId < lastInTrackId) {
192 return TrackingUtilities::EForwardBackward::c_Forward;
193 } else if (firstInTrackId > lastInTrackId) {
194 return TrackingUtilities::EForwardBackward::c_Backward;
195 } else if (firstInTrackId == lastInTrackId) {
196 return TrackingUtilities::EForwardBackward::c_Unknown;
197 }
198 return TrackingUtilities::EForwardBackward::c_Invalid;
199 }
200
201 template <class ACDCHitCollection>
203 const ACDCHitCollection* ptrFromHits,
204 const ACDCHitCollection* ptrToHits) const
205 {
207 ITrackType fromMCTrackId = getMCTrackId(ptrFromHits);
208 if (fromMCTrackId == INVALID_ITRACK) return TrackingUtilities::EForwardBackward::c_Invalid;
209
210 ITrackType toMCTrackId = getMCTrackId(ptrToHits);
211 if (toMCTrackId == INVALID_ITRACK) return TrackingUtilities::EForwardBackward::c_Invalid;
212
213 if (fromMCTrackId != toMCTrackId) return TrackingUtilities::EForwardBackward::c_Invalid;
214
215 // Check if the segments are meaningful on their own
216 TrackingUtilities::EForwardBackward fromFBInfo = isForwardOrBackwardToMCTrack(ptrFromHits);
217 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Invalid) return TrackingUtilities::EForwardBackward::c_Invalid;
218
219 TrackingUtilities::EForwardBackward toFBInfo = isForwardOrBackwardToMCTrack(ptrToHits);
220 if (toFBInfo == TrackingUtilities::EForwardBackward::c_Invalid) return TrackingUtilities::EForwardBackward::c_Invalid;
221
222 if (fromFBInfo != toFBInfo) return TrackingUtilities::EForwardBackward::c_Invalid;
223
224 {
225 // Now check if hits are aligned within their common track
226 // Index firstNPassedSuperLayersOfFromHits = getFirstNPassedSuperLayers(ptrFromHits);
227 TrackingUtilities::Index lastNPassedSuperLayersOfFromHits = getLastNPassedSuperLayers(ptrFromHits);
228 // if (firstNPassedSuperLayersOfFromHits == c_InvalidIndex) return
229 // EForwardBackward::c_Invalid;
230 if (lastNPassedSuperLayersOfFromHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
231
232 TrackingUtilities::Index firstNPassedSuperLayersOfToHits = getFirstNPassedSuperLayers(ptrToHits);
233 // Index lastNPassedSuperLayersOfToHits = getLastNPassedSuperLayers(ptrToHits);
234 if (firstNPassedSuperLayersOfToHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
235 // if (lastNPassedSuperLayersOfToHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
236
237 if (lastNPassedSuperLayersOfFromHits < firstNPassedSuperLayersOfToHits) {
238 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Forward and
239 toFBInfo == TrackingUtilities::EForwardBackward::c_Forward) {
240 return TrackingUtilities::EForwardBackward::c_Forward;
241 } else {
242 return TrackingUtilities::EForwardBackward::c_Invalid;
243 }
244 } else if (firstNPassedSuperLayersOfToHits < lastNPassedSuperLayersOfFromHits) {
245 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Backward and
246 toFBInfo == TrackingUtilities::EForwardBackward::c_Backward) {
247 return TrackingUtilities::EForwardBackward::c_Backward;
248 } else {
249 return TrackingUtilities::EForwardBackward::c_Invalid;
250 }
251 }
252 }
253
254 {
255 // Now we are in the same true segment with both segments
256 // Index firstInTrackSegmentIdOfFromHits = getFirstInTrackSegmentId(ptrFromHits);
257 TrackingUtilities::Index lastInTrackSegmentIdOfFromHits = getLastInTrackSegmentId(ptrFromHits);
258 // if (firstInTrackSegmentIdOfFromHits == c_InvalidIndex) return
259 // EForwardBackward::c_Invalid;
260 if (lastInTrackSegmentIdOfFromHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
261
262 TrackingUtilities::Index firstInTrackSegmentIdOfToHits = getFirstInTrackSegmentId(ptrToHits);
263 // Index lastInTrackSegmentIdOfToHits = getLastInTrackSegmentId(ptrToHits);
264 if (firstInTrackSegmentIdOfToHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
265 // if (lastInTrackSegmentIdOfToHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
266
267 if (lastInTrackSegmentIdOfFromHits < firstInTrackSegmentIdOfToHits) {
268 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Forward and
269 toFBInfo == TrackingUtilities::EForwardBackward::c_Forward) {
270 return TrackingUtilities::EForwardBackward::c_Forward;
271 } else {
272 return TrackingUtilities::EForwardBackward::c_Invalid;
273 }
274 } else if (firstInTrackSegmentIdOfToHits < lastInTrackSegmentIdOfFromHits) {
275 // Test if to segment lies before in the mc track
276 // Hence the whole pair of segments is reverse to the track direction of flight
277 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Backward and
278 toFBInfo == TrackingUtilities::EForwardBackward::c_Backward) {
279 return TrackingUtilities::EForwardBackward::c_Backward;
280 } else {
281 return TrackingUtilities::EForwardBackward::c_Invalid;
282 }
283 }
284 }
285
286 {
287 // Now we are in the same true segment with both of the hits
288 // Index firstInTrackIdOfFromHits = getFirstInTrackId(ptrFromHits);
289 TrackingUtilities::Index lastInTrackIdOfFromHits = getLastInTrackId(ptrFromHits);
290 // if (firstInTrackIdOfFromHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
291 if (lastInTrackIdOfFromHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
292
293 TrackingUtilities::Index firstInTrackIdOfToHits = getFirstInTrackId(ptrToHits);
294 // Index lastInTrackIdOfToHits = getLastInTrackId(ptrToHits);
295 if (firstInTrackIdOfToHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
296 // if (lastInTrackIdOfToHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
297
298 // Relax conditions somewhat such that segments may overlap at the borders.
299
300 if (lastInTrackIdOfFromHits - 1 < firstInTrackIdOfToHits + 1) {
301 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Forward and
302 toFBInfo == TrackingUtilities::EForwardBackward::c_Forward) {
303 return TrackingUtilities::EForwardBackward::c_Forward;
304 }
305 }
306
307 if (firstInTrackIdOfToHits - 1 < lastInTrackIdOfFromHits + 1) {
308 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Backward and
309 toFBInfo == TrackingUtilities::EForwardBackward::c_Backward) {
310 return TrackingUtilities::EForwardBackward::c_Backward;
311 }
312 }
313 }
314 // FIXME: Handle intertwined hits that are not cleanly consecutive along the track?
315 return TrackingUtilities::EForwardBackward::c_Invalid;
316 }
317
318 template <class ACDCHitCollection>
320 const ACDCHitCollection* ptrFromHits,
321 const ACDCHitCollection* ptrToHits) const
322 {
323 TrackingUtilities::EForwardBackward result = areAlignedInMCTrack(ptrFromHits, ptrToHits);
324 if (result == TrackingUtilities::EForwardBackward::c_Invalid) return result;
325
326 int fromCorrectRLVote = getCorrectRLVote(ptrFromHits);
327 int toCorrectRLVote = getCorrectRLVote(ptrToHits);
328
329 if (result == TrackingUtilities::EForwardBackward::c_Backward) {
330 fromCorrectRLVote = -fromCorrectRLVote;
331 toCorrectRLVote = -toCorrectRLVote;
332 }
333
334 int fromNCorrectRL = (fromCorrectRLVote + ptrFromHits->size()) / 2;
335 int toNCorrectRL = (toCorrectRLVote + ptrToHits->size()) / 2;
336
337 float fromRLPurity = 1.0 * fromNCorrectRL / ptrFromHits->size();
338 float toRLPurity = 1.0 * toNCorrectRL / ptrToHits->size();
339
340 // Require the minimal rl purity and also at least 2.5 correct hits
341 // (cut chosen to require all correct in single hit triplet segment)
342 if (fromRLPurity > m_minimalRLPurity and toRLPurity > m_minimalRLPurity and
343 fromNCorrectRL > 2.5 and toNCorrectRL > 2.5) {
344 return result;
345 }
346
347 return TrackingUtilities::EForwardBackward::c_Invalid;
348 }
349
350 template <class ACDCHitCollection>
352 const ACDCHitCollection* ptrHits) const
353 {
354 if (not ptrHits) {
355 B2WARNING("Segment is nullptr. Could not get fit.");
357 }
358
359 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
360
361 const CDCHit* ptrFirstHit = getFirstHit(ptrHits);
362 const CDCSimHit* ptrPrimarySimHit = mcHitLookUp.getClosestPrimarySimHit(ptrFirstHit);
363
364 if (not ptrPrimarySimHit) {
365 // If there is no primary SimHit simply use the secondary simhit as reference
366 ptrPrimarySimHit = mcHitLookUp.getSimHit(ptrFirstHit);
367 if (not ptrPrimarySimHit) {
369 }
370 }
371
372 const CDCSimHit& primarySimHit = *ptrPrimarySimHit;
373
374 TrackingUtilities::Vector3D mom3D{primarySimHit.getMomentum()};
375 TrackingUtilities::Vector3D pos3D{primarySimHit.getPosTrack()};
376 double time{primarySimHit.getFlightTime()};
377
378 int pdgCode = primarySimHit.getPDGCode();
379 const TParticlePDG* ptrTPDGParticle = TDatabasePDG::Instance()->GetParticle(pdgCode);
380
381 if (not ptrTPDGParticle) {
382 B2WARNING("No particle for PDG code " << pdgCode << ". Could not get fit");
384 }
385
386 const TParticlePDG& tPDGParticle = *ptrTPDGParticle;
387
388 double charge = tPDGParticle.Charge() / 3.0;
389
390 TrackingUtilities::ESign chargeSign = TrackingUtilities::sign(charge);
391
392 TrackingUtilities::CDCTrajectory3D trajectory3D(pos3D, time, mom3D, charge);
393
394 TrackingUtilities::ESign settedChargeSign = trajectory3D.getChargeSign();
395
396 if (chargeSign != settedChargeSign) {
397 B2WARNING("Charge sign of mc particle is not the same as the one of the fit");
398 }
399
400 return trajectory3D;
401 }
402 }
404}
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition CDCHit.h:40
Example Detector.
Definition CDCSimHit.h:21
int getPDGCode() const
The method to get PDG code.
Definition CDCSimHit.h:177
double getFlightTime() const
The method to get flight time.
Definition CDCSimHit.h:183
B2Vector3D getPosTrack() const
The method to get position on the track.
Definition CDCSimHit.h:216
B2Vector3D getMomentum() const
The method to get momentum.
Definition CDCSimHit.h:192
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
TrackingUtilities::Index getFirstInTrackId(const ACDCHitCollection *ptrHits) const
Getter for in track id for the first hit in the collection of hits which has the Monte Carlo track id...
ITrackType getMCTrackId(const ACDCHitCollection *ptrHits) const
Getter for the Monte Carlo track id matched to this collection of hits.
TrackingUtilities::Index getFirstInTrackSegmentId(const ACDCHitCollection *ptrHits) const
Getter for in track collection of hits id for the first hit in the collection of hits which has the M...
TrackingUtilities::EForwardBackward areAlignedInMCTrack(const ACDCHitCollection *ptrFromHits, const ACDCHitCollection *ptrToHits) const
Returns if the second collection of hits follows the first collection of hits in their common Monte C...
std::map< ITrackType, size_t > getHitCountByMCTrackId(const ACDCHitCollection &hits) const
Fill a map with the number of hits for each track id contained in the given hit range.
TrackingUtilities::EForwardBackward isForwardOrBackwardToMCTrack(const ACDCHitCollection *ptrHits) const
Returns the orientation of the collection of hits relative to its matched track.
MCTrackIdPurityPair getHighestPurity(const ACDCHitCollection &hits) const
Get the track id with the highest corresponding purity.
const CDCHit * getLastHit(const ACDCHitCollection *ptrHits) const
Getter for the last hit in the collection of hits which has the Monte Carlo track id matched to this ...
const MCParticle * getMCParticle(const ACDCHitCollection *ptrHits) const
Getter for the mc particle matched to this collection of hits.
TrackingUtilities::Index getLastNPassedSuperLayers(const ACDCHitCollection *ptrHits) const
Getter for number of passed superlayer till the last hit the collection of hits which has the Monte C...
int getCorrectRLVote(const ACDCHitCollection *ptrHits) const
Getter for the difference of correct versus incorrect right left passage information.
TrackingUtilities::Index getLastInTrackSegmentId(const ACDCHitCollection *ptrHits) const
Getter for in track collection of hits id for the last hit in the collection of hits which has the Mo...
void clear()
Clears all Monte Carlo information left from the last event.
const CDCHit * getFirstHit(const ACDCHitCollection *ptrHits) const
Getter for the first hit in the collection of hits which has the Monte Carlo track id matched to this...
double getRLPurity(const ACDCHitCollection *ptrHits) const
Getter for the right left passge purity which respects the forward backward reconstruction.
TrackingUtilities::Index getFirstNPassedSuperLayers(const ACDCHitCollection *ptrHits) const
Getter for number of passed superlayer till the first hit the collection of hits which has the Monte ...
TrackingUtilities::EForwardBackward areAlignedInMCTrackWithRLCheck(const ACDCHitCollection *ptrFromHits, const ACDCHitCollection *ptrToHits) const
Returns if the second collection of hits follows the first collection of hits in their common Monte C...
TrackingUtilities::CDCTrajectory3D getTrajectory3D(const ACDCHitCollection *ptrHits) const
Returns the trajectory of the collection of hits.
TrackingUtilities::Index getLastInTrackId(const ACDCHitCollection *ptrHits) const
Getter for in track id for the last hit in the collection of hits which has the Monte Carlo track id ...
float m_minimalRLPurity
Threshold for the correct fraction of right left passage information to be considered a match.
Interface class to the Monte Carlo information for individual hits.
const CDCSimHit * getClosestPrimarySimHit(const CDCHit *ptrHit) const
Getter for the closest simulated hit of a primary particle to the given hit - may return nullptr of n...
ITrackType getMCTrackId(const CDCHit *ptrHit) const
Returns the track id for the hit.
const Belle2::MCParticle * getMCParticle(const CDCHit *ptrHit) const
Getter for the MCParticle which is related to the CDCHit contained in the given wire hit.
const Belle2::CDCSimHit * getSimHit(const CDCHit *ptrHit) const
Getter for the CDCSimHit which is related to the CDCHit contained in the given wire hit.
static const CDCMCHitLookUp & getInstance()
Getter for the singletone instance.
TrackingUtilities::ERightLeft getRLInfo(const CDCHit *ptrHit) const
Returns the true right left passage information.
Particle full three dimensional trajectory.
ESign getChargeSign() const
Gets the charge sign of the trajectory.
A three dimensional vector.
Definition Vector3D.h:33
Abstract base class for different kinds of events.
Structure representing a matched Monte Carlo track id with the corresponding purity.
int getCorrectRLVote() const
Getter for the rl vote.
float getPurity() const
Getter for the purity.
ITrackType getMCTrackId() const
Getter for the Monte Carlo track Id.