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 <Math/Vector3D.h>
22#include <TDatabasePDG.h>
23
24namespace Belle2 {
29 namespace TrackFindingCDC {
30
31 template <class ACDCHitCollection>
33 {
34 B2DEBUG(25, "Clearing CDCMCHitCollectionLookUp<ACDCHitCollection>");
35 }
36
37 template <class ACDCHitCollection>
38 std::map<ITrackType, size_t>
40 const ACDCHitCollection& hits) const
41 {
42 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
43
44 std::map<ITrackType, size_t> hitCountByMCTrackId;
45 for (const CDCHit* ptrHit : hits) {
46 ITrackType mcTrackId = mcHitLookUp.getMCTrackId(ptrHit);
47 // cppcheck-suppress stlFindInsert
48 if (hitCountByMCTrackId.count(mcTrackId) == 0) hitCountByMCTrackId[mcTrackId] = 0;
49 ++(hitCountByMCTrackId[mcTrackId]);
50 }
51 return hitCountByMCTrackId;
52 }
53
54 template <class ACDCHitCollection>
56 const ACDCHitCollection& hits) const
57 {
58 std::map<ITrackType, size_t> hitCountByMCTrackId = getHitCountByMCTrackId(hits);
59
60 size_t nHits = 0;
61 std::pair<ITrackType, size_t> highestHitCountMCTrackId(0, 0);
62 static_cast<void>(std::max_element(hitCountByMCTrackId.begin(), hitCountByMCTrackId.end(),
63 TrackingUtilities::LessOf<TrackingUtilities::Second>()));
64
65 for (const auto& hitCountForMCTrackId : hitCountByMCTrackId) {
66
67 nHits += hitCountForMCTrackId.second;
68
69 if (highestHitCountMCTrackId.second < hitCountForMCTrackId.second) {
70 highestHitCountMCTrackId = hitCountForMCTrackId;
71 }
72 }
73
74 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
75
76 int correctRLVote = 0;
77 for (const auto& recoHit : hits) {
78 const CDCHit* hit = recoHit;
79 TrackingUtilities::ERightLeft mcRLInfo = mcHitLookUp.getRLInfo(hit);
80 TrackingUtilities::ERightLeft rlInfo = recoHit.getRLInfo();
81 if (rlInfo == mcRLInfo) {
82 ++correctRLVote;
83 } else {
84 --correctRLVote;
85 }
86 }
87
88 const float purity = static_cast<float>(highestHitCountMCTrackId.second) / nHits;
89 return MCTrackIdPurityPair(highestHitCountMCTrackId.first, purity, correctRLVote);
90 }
91
92 template <class ACDCHitCollection>
93 ITrackType
94 CDCMCHitCollectionLookUp<ACDCHitCollection>::getMCTrackId(const ACDCHitCollection* ptrHits) const
95 {
96 if (not ptrHits) return INVALID_ITRACK;
97 const ACDCHitCollection& hits = *ptrHits;
98 MCTrackIdPurityPair mcTrackIdAndPurity = getHighestPurity(hits);
99 if (mcTrackIdAndPurity.getPurity() >= m_minimalMatchPurity) {
100 return mcTrackIdAndPurity.getMCTrackId();
101 } else {
102 return INVALID_ITRACK;
103 }
105
106 template <class ACDCHitCollection>
108 const ACDCHitCollection* ptrHits) const
109 {
110 if (not ptrHits) return INVALID_ITRACK;
111 const ACDCHitCollection& hits = *ptrHits;
112 MCTrackIdPurityPair mcTrackIdAndPurity = getHighestPurity(hits);
113 if (mcTrackIdAndPurity.getPurity() >= m_minimalMatchPurity) {
114 return mcTrackIdAndPurity.getCorrectRLVote();
115 } else {
116 return 0;
117 }
118 }
119
120 template <class ACDCHitCollection>
121 double
122 CDCMCHitCollectionLookUp<ACDCHitCollection>::getRLPurity(const ACDCHitCollection* ptrHits) const
123 {
124 TrackingUtilities::EForwardBackward fbInfo = isForwardOrBackwardToMCTrack(ptrHits);
125 if (fbInfo == TrackingUtilities::EForwardBackward::c_Invalid) return NAN;
126
127 int correctRLVote = getCorrectRLVote(ptrHits);
128
129 if (fbInfo == TrackingUtilities::EForwardBackward::c_Backward) {
130 correctRLVote = -correctRLVote;
131 }
132
133 int nCorrectRL = (correctRLVote + ptrHits->size()) / 2;
134 float rlPurity = 1.0 * nCorrectRL / ptrHits->size();
135 return rlPurity;
136 }
137
138 template <class ACDCHitCollection>
140 const ACDCHitCollection* ptrHits) const
141 {
142 const CDCHit* ptrHit = getFirstHit(ptrHits);
143 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
144 return mcHitLookUp.getMCParticle(ptrHit);
145 }
146
147 template <class ACDCHitCollection>
148 const CDCHit*
149 CDCMCHitCollectionLookUp<ACDCHitCollection>::getFirstHit(const ACDCHitCollection* ptrHits) const
150 {
151 if (not ptrHits) return nullptr;
152 const ACDCHitCollection& hits = *ptrHits;
153
154 ITrackType mcTrackId = getMCTrackId(ptrHits);
155 if (mcTrackId == INVALID_ITRACK) return nullptr;
156
157 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
159 for (const CDCHit* hit : hits) {
160 if (mcTrackId == mcHitLookUp.getMCTrackId(hit)) return hit;
161 }
162 return nullptr;
163 }
164
165 template <class ACDCHitCollection>
166 const CDCHit*
167 CDCMCHitCollectionLookUp<ACDCHitCollection>::getLastHit(const ACDCHitCollection* ptrHits) const
168 {
169
170 if (not ptrHits) return nullptr;
171 const ACDCHitCollection& hits = *ptrHits;
172
173 ITrackType mcTrackId = getMCTrackId(ptrHits);
174 if (mcTrackId == INVALID_ITRACK) return nullptr;
175
176 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
177
178 for (const CDCHit* hit : TrackingUtilities::reversedRange(hits)) {
179 if (mcTrackId == mcHitLookUp.getMCTrackId(hit)) return hit;
180 }
181 return nullptr;
182 }
184 template <class ACDCHitCollection>
186 const ACDCHitCollection* ptrHits) const
187 {
188 TrackingUtilities::Index firstInTrackId = getFirstInTrackId(ptrHits);
189 TrackingUtilities::Index lastInTrackId = getLastInTrackId(ptrHits);
190 if (firstInTrackId == TrackingUtilities::c_InvalidIndex or lastInTrackId == TrackingUtilities::c_InvalidIndex) {
191 return TrackingUtilities::EForwardBackward::c_Invalid;
192 } else if (firstInTrackId < lastInTrackId) {
193 return TrackingUtilities::EForwardBackward::c_Forward;
194 } else if (firstInTrackId > lastInTrackId) {
195 return TrackingUtilities::EForwardBackward::c_Backward;
196 } else if (firstInTrackId == lastInTrackId) {
197 return TrackingUtilities::EForwardBackward::c_Unknown;
198 }
199 return TrackingUtilities::EForwardBackward::c_Invalid;
200 }
201
202 template <class ACDCHitCollection>
204 const ACDCHitCollection* ptrFromHits,
205 const ACDCHitCollection* ptrToHits) const
206 {
208 ITrackType fromMCTrackId = getMCTrackId(ptrFromHits);
209 if (fromMCTrackId == INVALID_ITRACK) return TrackingUtilities::EForwardBackward::c_Invalid;
210
211 ITrackType toMCTrackId = getMCTrackId(ptrToHits);
212 if (toMCTrackId == INVALID_ITRACK) return TrackingUtilities::EForwardBackward::c_Invalid;
213
214 if (fromMCTrackId != toMCTrackId) return TrackingUtilities::EForwardBackward::c_Invalid;
215
216 // Check if the segments are meaningful on their own
217 TrackingUtilities::EForwardBackward fromFBInfo = isForwardOrBackwardToMCTrack(ptrFromHits);
218 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Invalid) return TrackingUtilities::EForwardBackward::c_Invalid;
219
220 TrackingUtilities::EForwardBackward toFBInfo = isForwardOrBackwardToMCTrack(ptrToHits);
221 if (toFBInfo == TrackingUtilities::EForwardBackward::c_Invalid) return TrackingUtilities::EForwardBackward::c_Invalid;
222
223 if (fromFBInfo != toFBInfo) return TrackingUtilities::EForwardBackward::c_Invalid;
224
225 {
226 // Now check if hits are aligned within their common track
227 // Index firstNPassedSuperLayersOfFromHits = getFirstNPassedSuperLayers(ptrFromHits);
228 TrackingUtilities::Index lastNPassedSuperLayersOfFromHits = getLastNPassedSuperLayers(ptrFromHits);
229 // if (firstNPassedSuperLayersOfFromHits == c_InvalidIndex) return
230 // EForwardBackward::c_Invalid;
231 if (lastNPassedSuperLayersOfFromHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
232
233 TrackingUtilities::Index firstNPassedSuperLayersOfToHits = getFirstNPassedSuperLayers(ptrToHits);
234 // Index lastNPassedSuperLayersOfToHits = getLastNPassedSuperLayers(ptrToHits);
235 if (firstNPassedSuperLayersOfToHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
236 // if (lastNPassedSuperLayersOfToHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
237
238 if (lastNPassedSuperLayersOfFromHits < firstNPassedSuperLayersOfToHits) {
239 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Forward and
240 toFBInfo == TrackingUtilities::EForwardBackward::c_Forward) {
241 return TrackingUtilities::EForwardBackward::c_Forward;
242 } else {
243 return TrackingUtilities::EForwardBackward::c_Invalid;
244 }
245 } else if (firstNPassedSuperLayersOfToHits < lastNPassedSuperLayersOfFromHits) {
246 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Backward and
247 toFBInfo == TrackingUtilities::EForwardBackward::c_Backward) {
248 return TrackingUtilities::EForwardBackward::c_Backward;
249 } else {
250 return TrackingUtilities::EForwardBackward::c_Invalid;
251 }
252 }
253 }
254
255 {
256 // Now we are in the same true segment with both segments
257 // Index firstInTrackSegmentIdOfFromHits = getFirstInTrackSegmentId(ptrFromHits);
258 TrackingUtilities::Index lastInTrackSegmentIdOfFromHits = getLastInTrackSegmentId(ptrFromHits);
259 // if (firstInTrackSegmentIdOfFromHits == c_InvalidIndex) return
260 // EForwardBackward::c_Invalid;
261 if (lastInTrackSegmentIdOfFromHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
262
263 TrackingUtilities::Index firstInTrackSegmentIdOfToHits = getFirstInTrackSegmentId(ptrToHits);
264 // Index lastInTrackSegmentIdOfToHits = getLastInTrackSegmentId(ptrToHits);
265 if (firstInTrackSegmentIdOfToHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
266 // if (lastInTrackSegmentIdOfToHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
267
268 if (lastInTrackSegmentIdOfFromHits < firstInTrackSegmentIdOfToHits) {
269 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Forward and
270 toFBInfo == TrackingUtilities::EForwardBackward::c_Forward) {
271 return TrackingUtilities::EForwardBackward::c_Forward;
272 } else {
273 return TrackingUtilities::EForwardBackward::c_Invalid;
274 }
275 } else if (firstInTrackSegmentIdOfToHits < lastInTrackSegmentIdOfFromHits) {
276 // Test if to segment lies before in the mc track
277 // Hence the whole pair of segments is reverse to the track direction of flight
278 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Backward and
279 toFBInfo == TrackingUtilities::EForwardBackward::c_Backward) {
280 return TrackingUtilities::EForwardBackward::c_Backward;
281 } else {
282 return TrackingUtilities::EForwardBackward::c_Invalid;
283 }
284 }
285 }
286
287 {
288 // Now we are in the same true segment with both of the hits
289 // Index firstInTrackIdOfFromHits = getFirstInTrackId(ptrFromHits);
290 TrackingUtilities::Index lastInTrackIdOfFromHits = getLastInTrackId(ptrFromHits);
291 // if (firstInTrackIdOfFromHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
292 if (lastInTrackIdOfFromHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
293
294 TrackingUtilities::Index firstInTrackIdOfToHits = getFirstInTrackId(ptrToHits);
295 // Index lastInTrackIdOfToHits = getLastInTrackId(ptrToHits);
296 if (firstInTrackIdOfToHits == TrackingUtilities::c_InvalidIndex) return TrackingUtilities::EForwardBackward::c_Invalid;
297 // if (lastInTrackIdOfToHits == c_InvalidIndex) return EForwardBackward::c_Invalid;
298
299 // Relax conditions somewhat such that segments may overlap at the borders.
300
301 if (lastInTrackIdOfFromHits - 1 < firstInTrackIdOfToHits + 1) {
302 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Forward and
303 toFBInfo == TrackingUtilities::EForwardBackward::c_Forward) {
304 return TrackingUtilities::EForwardBackward::c_Forward;
305 }
306 }
307
308 if (firstInTrackIdOfToHits - 1 < lastInTrackIdOfFromHits + 1) {
309 if (fromFBInfo == TrackingUtilities::EForwardBackward::c_Backward and
310 toFBInfo == TrackingUtilities::EForwardBackward::c_Backward) {
311 return TrackingUtilities::EForwardBackward::c_Backward;
312 }
313 }
314 }
315 // FIXME: Handle intertwined hits that are not cleanly consecutive along the track?
316 return TrackingUtilities::EForwardBackward::c_Invalid;
317 }
318
319 template <class ACDCHitCollection>
321 const ACDCHitCollection* ptrFromHits,
322 const ACDCHitCollection* ptrToHits) const
323 {
324 TrackingUtilities::EForwardBackward result = areAlignedInMCTrack(ptrFromHits, ptrToHits);
325 if (result == TrackingUtilities::EForwardBackward::c_Invalid) return result;
326
327 int fromCorrectRLVote = getCorrectRLVote(ptrFromHits);
328 int toCorrectRLVote = getCorrectRLVote(ptrToHits);
329
330 if (result == TrackingUtilities::EForwardBackward::c_Backward) {
331 fromCorrectRLVote = -fromCorrectRLVote;
332 toCorrectRLVote = -toCorrectRLVote;
333 }
334
335 int fromNCorrectRL = (fromCorrectRLVote + ptrFromHits->size()) / 2;
336 int toNCorrectRL = (toCorrectRLVote + ptrToHits->size()) / 2;
337
338 float fromRLPurity = 1.0 * fromNCorrectRL / ptrFromHits->size();
339 float toRLPurity = 1.0 * toNCorrectRL / ptrToHits->size();
340
341 // Require the minimal rl purity and also at least 2.5 correct hits
342 // (cut chosen to require all correct in single hit triplet segment)
343 if (fromRLPurity > m_minimalRLPurity and toRLPurity > m_minimalRLPurity and
344 fromNCorrectRL > 2.5 and toNCorrectRL > 2.5) {
345 return result;
346 }
347
348 return TrackingUtilities::EForwardBackward::c_Invalid;
349 }
350
351 template <class ACDCHitCollection>
353 const ACDCHitCollection* ptrHits) const
354 {
355 if (not ptrHits) {
356 B2WARNING("Segment is nullptr. Could not get fit.");
358 }
359
360 const CDCMCHitLookUp& mcHitLookUp = CDCMCHitLookUp::getInstance();
361
362 const CDCHit* ptrFirstHit = getFirstHit(ptrHits);
363 const CDCSimHit* ptrPrimarySimHit = mcHitLookUp.getClosestPrimarySimHit(ptrFirstHit);
364
365 if (not ptrPrimarySimHit) {
366 // If there is no primary SimHit simply use the secondary simhit as reference
367 ptrPrimarySimHit = mcHitLookUp.getSimHit(ptrFirstHit);
368 if (not ptrPrimarySimHit) {
370 }
371 }
372
373 const CDCSimHit& primarySimHit = *ptrPrimarySimHit;
374
375 ROOT::Math::XYZVector mom3D{primarySimHit.getMomentum()};
376 ROOT::Math::XYZVector pos3D{primarySimHit.getPosTrack()};
377 double time{primarySimHit.getFlightTime()};
378
379 int pdgCode = primarySimHit.getPDGCode();
380 const TParticlePDG* ptrTPDGParticle = TDatabasePDG::Instance()->GetParticle(pdgCode);
381
382 if (not ptrTPDGParticle) {
383 B2WARNING("No particle for PDG code " << pdgCode << ". Could not get fit");
385 }
386
387 const TParticlePDG& tPDGParticle = *ptrTPDGParticle;
388
389 double charge = tPDGParticle.Charge() / 3.0;
390
391 TrackingUtilities::ESign chargeSign = TrackingUtilities::sign(charge);
392
393 TrackingUtilities::CDCTrajectory3D trajectory3D(pos3D, time, mom3D, charge);
394
395 TrackingUtilities::ESign settedChargeSign = trajectory3D.getChargeSign();
396
397 if (chargeSign != settedChargeSign) {
398 B2WARNING("Charge sign of mc particle is not the same as the one of the fit");
399 }
400
401 return trajectory3D;
402 }
403 }
405}
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.
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.