12 #include <tracking/trackFindingCDC/mclookup/CDCMCHitCollectionLookUp.h>
14 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory3D.h>
16 #include <tracking/trackFindingCDC/utilities/ReversedRange.h>
17 #include <tracking/trackFindingCDC/utilities/Functional.h>
19 #include <cdc/dataobjects/CDCHit.h>
20 #include <cdc/dataobjects/CDCSimHit.h>
21 #include <mdst/dataobjects/MCParticle.h>
23 #include <TDatabasePDG.h>
30 namespace TrackFindingCDC {
32 template <
class ACDCHitCollection>
35 B2DEBUG(100,
"Clearing CDCMCHitCollectionLookUp<ACDCHitCollection>");
38 template <
class ACDCHitCollection>
39 std::map<ITrackType, size_t>
41 const ACDCHitCollection& hits)
const
45 std::map<ITrackType, size_t> hitCountByMCTrackId;
46 for (
const CDCHit* ptrHit : hits) {
48 if (hitCountByMCTrackId.count(mcTrackId) == 0) hitCountByMCTrackId[mcTrackId] = 0;
49 ++(hitCountByMCTrackId[mcTrackId]);
51 return hitCountByMCTrackId;
54 template <
class ACDCHitCollection>
56 const ACDCHitCollection& hits)
const
58 std::map<ITrackType, size_t> hitCountByMCTrackId = getHitCountByMCTrackId(hits);
61 std::pair<ITrackType, size_t> highestHitCountMCTrackId(0, 0);
62 std::max_element(hitCountByMCTrackId.begin(), hitCountByMCTrackId.end(), LessOf<Second>());
64 for (
const std::pair<ITrackType, size_t>& hitCountForMCTrackId : hitCountByMCTrackId) {
66 nHits += hitCountForMCTrackId.second;
68 if (highestHitCountMCTrackId.second < hitCountForMCTrackId.second) {
69 highestHitCountMCTrackId = hitCountForMCTrackId;
75 int correctRLVote = 0;
76 for (
const auto& recoHit : hits) {
77 const CDCHit* hit = recoHit;
80 if (rlInfo == mcRLInfo) {
87 const float purity =
static_cast<float>(highestHitCountMCTrackId.second) / nHits;
88 return MCTrackIdPurityPair(highestHitCountMCTrackId.first, purity, correctRLVote);
91 template <
class ACDCHitCollection>
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();
101 return INVALID_ITRACK;
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();
119 template <
class ACDCHitCollection>
123 EForwardBackward fbInfo = isForwardOrBackwardToMCTrack(ptrHits);
124 if (fbInfo == EForwardBackward::c_Invalid)
return NAN;
126 int correctRLVote = getCorrectRLVote(ptrHits);
128 if (fbInfo == EForwardBackward::c_Backward) {
129 correctRLVote = -correctRLVote;
132 int nCorrectRL = (correctRLVote + ptrHits->size()) / 2;
133 float rlPurity = 1.0 * nCorrectRL / ptrHits->size();
137 template <
class ACDCHitCollection>
139 const ACDCHitCollection* ptrHits)
const
141 const CDCHit* ptrHit = getFirstHit(ptrHits);
143 return mcHitLookUp.getMCParticle(ptrHit);
146 template <
class ACDCHitCollection>
150 if (not ptrHits)
return nullptr;
151 const ACDCHitCollection& hits = *ptrHits;
153 ITrackType mcTrackId = getMCTrackId(ptrHits);
154 if (mcTrackId == INVALID_ITRACK)
return nullptr;
158 for (
const CDCHit* hit : hits) {
159 if (mcTrackId == mcHitLookUp.
getMCTrackId(hit))
return hit;
164 template <
class ACDCHitCollection>
169 if (not ptrHits)
return nullptr;
170 const ACDCHitCollection& hits = *ptrHits;
172 ITrackType mcTrackId = getMCTrackId(ptrHits);
173 if (mcTrackId == INVALID_ITRACK)
return nullptr;
177 for (
const CDCHit* hit : reversedRange(hits)) {
178 if (mcTrackId == mcHitLookUp.
getMCTrackId(hit))
return hit;
183 template <
class ACDCHitCollection>
185 const ACDCHitCollection* ptrHits)
const
187 Index firstInTrackId = getFirstInTrackId(ptrHits);
188 Index lastInTrackId = getLastInTrackId(ptrHits);
189 if (firstInTrackId == c_InvalidIndex or lastInTrackId == c_InvalidIndex) {
190 return EForwardBackward::c_Invalid;
191 }
else if (firstInTrackId < lastInTrackId) {
192 return EForwardBackward::c_Forward;
193 }
else if (firstInTrackId > lastInTrackId) {
194 return EForwardBackward::c_Backward;
195 }
else if (firstInTrackId == lastInTrackId) {
196 return EForwardBackward::c_Unknown;
198 return EForwardBackward::c_Invalid;
201 template <
class ACDCHitCollection>
203 const ACDCHitCollection* ptrFromHits,
204 const ACDCHitCollection* ptrToHits)
const
207 ITrackType fromMCTrackId = getMCTrackId(ptrFromHits);
208 if (fromMCTrackId == INVALID_ITRACK)
return EForwardBackward::c_Invalid;
210 ITrackType toMCTrackId = getMCTrackId(ptrToHits);
211 if (toMCTrackId == INVALID_ITRACK)
return EForwardBackward::c_Invalid;
213 if (fromMCTrackId != toMCTrackId)
return EForwardBackward::c_Invalid;
217 if (fromFBInfo == EForwardBackward::c_Invalid)
return EForwardBackward::c_Invalid;
220 if (toFBInfo == EForwardBackward::c_Invalid)
return EForwardBackward::c_Invalid;
222 if (fromFBInfo != toFBInfo)
return EForwardBackward::c_Invalid;
227 Index lastNPassedSuperLayersOfFromHits = getLastNPassedSuperLayers(ptrFromHits);
230 if (lastNPassedSuperLayersOfFromHits == c_InvalidIndex)
return EForwardBackward::c_Invalid;
232 Index firstNPassedSuperLayersOfToHits = getFirstNPassedSuperLayers(ptrToHits);
234 if (firstNPassedSuperLayersOfToHits == c_InvalidIndex)
return EForwardBackward::c_Invalid;
237 if (lastNPassedSuperLayersOfFromHits < firstNPassedSuperLayersOfToHits) {
238 if (fromFBInfo == EForwardBackward::c_Forward and
239 toFBInfo == EForwardBackward::c_Forward) {
240 return EForwardBackward::c_Forward;
242 return EForwardBackward::c_Invalid;
244 }
else if (firstNPassedSuperLayersOfToHits < lastNPassedSuperLayersOfFromHits) {
245 if (fromFBInfo == EForwardBackward::c_Backward and
246 toFBInfo == EForwardBackward::c_Backward) {
247 return EForwardBackward::c_Backward;
249 return EForwardBackward::c_Invalid;
257 Index lastInTrackSegmentIdOfFromHits = getLastInTrackSegmentId(ptrFromHits);
260 if (lastInTrackSegmentIdOfFromHits == c_InvalidIndex)
return EForwardBackward::c_Invalid;
262 Index firstInTrackSegmentIdOfToHits = getFirstInTrackSegmentId(ptrToHits);
264 if (firstInTrackSegmentIdOfToHits == c_InvalidIndex)
return EForwardBackward::c_Invalid;
267 if (lastInTrackSegmentIdOfFromHits < firstInTrackSegmentIdOfToHits) {
268 if (fromFBInfo == EForwardBackward::c_Forward and
269 toFBInfo == EForwardBackward::c_Forward) {
270 return EForwardBackward::c_Forward;
272 return EForwardBackward::c_Invalid;
274 }
else if (firstInTrackSegmentIdOfToHits < lastInTrackSegmentIdOfFromHits) {
277 if (fromFBInfo == EForwardBackward::c_Backward and
278 toFBInfo == EForwardBackward::c_Backward) {
279 return EForwardBackward::c_Backward;
281 return EForwardBackward::c_Invalid;
289 Index lastInTrackIdOfFromHits = getLastInTrackId(ptrFromHits);
291 if (lastInTrackIdOfFromHits == c_InvalidIndex)
return EForwardBackward::c_Invalid;
293 Index firstInTrackIdOfToHits = getFirstInTrackId(ptrToHits);
295 if (firstInTrackIdOfToHits == c_InvalidIndex)
return EForwardBackward::c_Invalid;
300 if (lastInTrackIdOfFromHits - 1 < firstInTrackIdOfToHits + 1) {
301 if (fromFBInfo == EForwardBackward::c_Forward and
302 toFBInfo == EForwardBackward::c_Forward) {
303 return EForwardBackward::c_Forward;
307 if (firstInTrackIdOfToHits - 1 < lastInTrackIdOfFromHits + 1) {
308 if (fromFBInfo == EForwardBackward::c_Backward and
309 toFBInfo == EForwardBackward::c_Backward) {
310 return EForwardBackward::c_Backward;
315 return EForwardBackward::c_Invalid;
318 template <
class ACDCHitCollection>
320 const ACDCHitCollection* ptrFromHits,
321 const ACDCHitCollection* ptrToHits)
const
324 if (result == EForwardBackward::c_Invalid)
return result;
326 int fromCorrectRLVote = getCorrectRLVote(ptrFromHits);
327 int toCorrectRLVote = getCorrectRLVote(ptrToHits);
329 if (result == EForwardBackward::c_Backward) {
330 fromCorrectRLVote = -fromCorrectRLVote;
331 toCorrectRLVote = -toCorrectRLVote;
334 int fromNCorrectRL = (fromCorrectRLVote + ptrFromHits->size()) / 2;
335 int toNCorrectRL = (toCorrectRLVote + ptrToHits->size()) / 2;
337 float fromRLPurity = 1.0 * fromNCorrectRL / ptrFromHits->size();
338 float toRLPurity = 1.0 * toNCorrectRL / ptrToHits->size();
342 if (fromRLPurity > m_minimalRLPurity and toRLPurity > m_minimalRLPurity and
343 fromNCorrectRL > 2.5 and toNCorrectRL > 2.5) {
347 return EForwardBackward::c_Invalid;
350 template <
class ACDCHitCollection>
352 const ACDCHitCollection* ptrHits)
const
355 B2WARNING(
"Segment is nullptr. Could not get fit.");
356 return CDCTrajectory3D();
361 const CDCHit* ptrFirstHit = getFirstHit(ptrHits);
364 if (not ptrPrimarySimHit) {
366 ptrPrimarySimHit = mcHitLookUp.
getSimHit(ptrFirstHit);
367 if (not ptrPrimarySimHit) {
372 const CDCSimHit& primarySimHit = *ptrPrimarySimHit;
379 const TParticlePDG* ptrTPDGParticle = TDatabasePDG::Instance()->GetParticle(pdgCode);
381 if (not ptrTPDGParticle) {
382 B2WARNING(
"No particle for PDG code " << pdgCode <<
". Could not get fit");
383 return CDCTrajectory3D();
386 const TParticlePDG& tPDGParticle = *ptrTPDGParticle;
388 double charge = tPDGParticle.Charge() / 3.0;
390 ESign chargeSign = sign(charge);
392 CDCTrajectory3D trajectory3D(pos3D, time, mom3D, charge);
394 ESign settedChargeSign = trajectory3D.getChargeSign();
396 if (chargeSign != settedChargeSign) {
397 B2WARNING(
"Charge sign of mc particle is not the same as the one of the fit");