Belle II Software development
CDCSimHitLookUp.cc
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#include <tracking/trackFindingCDC/mclookup/CDCSimHitLookUp.h>
9
10#include <tracking/trackFindingCDC/mclookup/CDCMCManager.h>
11#include <tracking/trackFindingCDC/mclookup/CDCMCMap.h>
12
13#include <tracking/trackingUtilities/eventdata/hits/CDCRecoHit3D.h>
14#include <tracking/trackingUtilities/eventdata/hits/CDCRecoHit2D.h>
15#include <tracking/trackingUtilities/eventdata/hits/CDCWireHit.h>
16
17#include <cdc/topology/CDCWireTopology.h>
18
19#include <tracking/trackingUtilities/geometry/VectorUtil.h>
20
21#include <tracking/trackingUtilities/utilities/VectorRange.h>
22
23#include <cdc/dataobjects/CDCSimHit.h>
24#include <cdc/dataobjects/CDCHit.h>
25
26#include <vector>
27
28using namespace Belle2;
29using namespace CDC;
30using namespace TrackFindingCDC;
31using namespace TrackingUtilities;
32
37
39{
40 m_ptrMCMap = nullptr;
41
42 m_primarySimHits.clear();
43 m_rightLeftInfos.clear();
44}
45
46void CDCSimHitLookUp::fill(const CDCMCMap* ptrMCMap)
47{
48 B2DEBUG(25, "In CDCSimHitLookUp::fill()");
49 clear();
50 m_ptrMCMap = ptrMCMap;
51
53 fillRLInfo();
54
55 B2DEBUG(25, "m_primarySimHits.size(): " << m_primarySimHits.size());
56 B2DEBUG(25, "m_rightLeftInfos.size(): " << m_rightLeftInfos.size());
57}
58
60{
61 if (not m_ptrMCMap) {
62 B2WARNING("CDCMCMap not set. Cannot setup primary sim hit map");
63 return;
64 }
65
66 const CDCMCMap& mcMap = *m_ptrMCMap;
67 int nMissingPrimarySimHits = 0;
68 for (const auto& relation : mcMap.getSimHitsByHit()) {
69
70 const CDCHit* ptrHit = std::get<const CDCHit* const>(relation);
71 const CDCSimHit* ptrSimHit = std::get<const CDCSimHit*>(relation);
72
73 if (not ptrSimHit) {
74 B2ERROR("CDCHit has no related CDCSimHit in CDCSimHitLookUp::fill()");
75 continue;
76 }
77
78 if (mcMap.isReassignedSecondary(ptrSimHit)) {
79 MayBePtr<const CDCSimHit> primarySimHit = getClosestPrimarySimHit(ptrSimHit);
80 if (not primarySimHit) {
81 ++nMissingPrimarySimHits;
82 }
83 m_primarySimHits[ptrHit] = primarySimHit;
84 }
85 }
86 if (nMissingPrimarySimHits != 0) {
87 B2WARNING("NO primary hit found for " << nMissingPrimarySimHits << " reassigned secondaries");
88 }
89}
90
91MayBePtr<const CDCSimHit> CDCSimHitLookUp::getClosestPrimarySimHit(const CDCSimHit* ptrSimHit) const
92{
93 if (not ptrSimHit) {
94 return nullptr;
95 }
96 const CDCSimHit& simHit = *ptrSimHit;
97
98 if (not m_ptrMCMap) {
99 B2WARNING("CDCMCMap not set. Cannot find primary sim hit");
100 return nullptr;
101 }
102
103 const CDCMCMap& mcMap = *m_ptrMCMap;
104
105 // Check if the CDCSimHit was reassigned from a secondary particle to its primary particle.
106 if (not mcMap.isReassignedSecondary(ptrSimHit)) {
107 return ptrSimHit;
108 } else {
109
110 // Try to find the hit on the same wire from the primary particle.
111 const MCParticle* ptrMCParticle = mcMap.getMCParticle(ptrSimHit);
112 if (not ptrMCParticle) {
113 return nullptr;
114 }
115
116 WireID wireID = simHit.getWireID();
117 std::vector<const CDCSimHit*> primarySimHitsOnSameOrNeighborWire;
118 const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
119
120 for (const auto& simHitByMCParticleRelation : mcMap.getSimHits(ptrMCParticle)) {
121
122 const CDCSimHit* ptrPrimarySimHit = std::get<const CDCSimHit*>(simHitByMCParticleRelation);
123 if (mcMap.isReassignedSecondary(ptrPrimarySimHit) or not ptrPrimarySimHit) continue;
124
125 const CDCSimHit& primarySimHit = *ptrPrimarySimHit;
126
127 if (wireTopology.arePrimaryNeighbors(primarySimHit.getWireID(), wireID) or
128 primarySimHit.getWireID() == wireID) {
129
130 // Found a hit on the same wire from the primary particle.
131 primarySimHitsOnSameOrNeighborWire.push_back(ptrPrimarySimHit);
132 }
133 }
134
135 // Now from the neighboring primary CDCSimHits pick to one with the smallest distance to the
136 // secondary CDCSimHit.
137 auto compareDistanceBetweenSimHits =
138 [&simHit](const CDCSimHit * primarySimHit,
139 const CDCSimHit * otherPrimarySimHit) -> bool {
140 ROOT::Math::XYZVector primaryHitPos(primarySimHit->getPosTrack());
141 ROOT::Math::XYZVector otherPrimaryHitPos(otherPrimarySimHit->getPosTrack());
142 ROOT::Math::XYZVector secondaryHitPos(simHit.getPosTrack());
143 return VectorUtil::Distance(primaryHitPos, secondaryHitPos) < VectorUtil::Distance(otherPrimaryHitPos, secondaryHitPos);
144 };
145
146 auto itClosestPrimarySimHit = std::min_element(primarySimHitsOnSameOrNeighborWire.begin(),
147 primarySimHitsOnSameOrNeighborWire.end(),
148 compareDistanceBetweenSimHits);
149
150 if (itClosestPrimarySimHit != primarySimHitsOnSameOrNeighborWire.end()) {
151 // Found primary simulated hit for secondary hit.
152 return *itClosestPrimarySimHit;
153 } else {
154 return nullptr;
155 }
156 }
157}
158
160{
161 if (not m_ptrMCMap) {
162 B2WARNING("CDCMCMap not set in look up of closest primary sim hit.");
163 return nullptr;
164 }
165 const CDCMCMap& mcMap = *m_ptrMCMap;
166
167 if (mcMap.isReassignedSecondary(ptrHit)) {
168 auto itFoundPrimarySimHit = m_primarySimHits.find(ptrHit);
169 if (itFoundPrimarySimHit != m_primarySimHits.end()) {
170 const CDCSimHit* simHit = itFoundPrimarySimHit->second;
171 if (simHit) return simHit;
172 }
173 }
174 // Return the normal (potentially secondary) CDCSimHit of no primary is available
175 return mcMap.getSimHit(ptrHit);
176}
177
178ROOT::Math::XYZVector CDCSimHitLookUp::getDirectionOfFlight(const CDCHit* ptrHit)
179{
180 if (not ptrHit) return ROOT::Math::XYZVector();
181
182 if (not m_ptrMCMap) {
183 B2WARNING("CDCMCMap not set. Cannot find direction of flight");
184 return ROOT::Math::XYZVector();
185 }
186
187 const CDCMCMap& mcMap = *m_ptrMCMap;
188
189 const CDCSimHit* ptrSimHit = mcMap.getSimHit(ptrHit);
190
191 if (not ptrSimHit) return ROOT::Math::XYZVector();
192
193 const CDCSimHit* ptrPrimarySimHit =
194 mcMap.isReassignedSecondary(ptrHit) ? getClosestPrimarySimHit(ptrHit) : ptrSimHit;
195
196 if (not ptrPrimarySimHit) {
197 // if no primary simhit is close to the secondary hit we can only take the secondary
198 ptrPrimarySimHit = ptrSimHit;
199
200 // or invent something better at some point...
201 }
202
203 const CDCSimHit& primarySimHit = *ptrPrimarySimHit;
204
205 // Take the momentum of the primary hit
206 ROOT::Math::XYZVector directionOfFlight{primarySimHit.getMomentum()};
207 return directionOfFlight;
208}
209
211{
212
213 if (not m_ptrMCMap) {
214 B2WARNING("CDCMCMap not set. Cannot setup right left passage information map");
215 return;
216 }
217 const CDCMCMap& mcMap = *m_ptrMCMap;
218
219 for (const auto& relation : mcMap.getSimHitsByHit()) {
220
221 const CDCHit* ptrHit = std::get<const CDCHit* const>(relation);
222 const CDCSimHit* ptrSimHit = std::get<const CDCSimHit*>(relation);
223
224 if (not ptrSimHit) continue;
225 const CDCSimHit& simHit = *ptrSimHit;
226
227 ROOT::Math::XYZVector directionOfFlight = getDirectionOfFlight(ptrHit);
228 if (VectorUtil::isNull(directionOfFlight)) continue;
229
230 // find out if the wire is right or left of the track ( view in flight direction )
231 ROOT::Math::XYZVector trackPosToWire{simHit.getPosWire() - simHit.getPosTrack()};
232 ERightLeft rlInfo = VectorUtil::isRightOrLeftOf(VectorUtil::getXYVector(trackPosToWire),
233 VectorUtil::getXYVector(directionOfFlight));
234 m_rightLeftInfos[ptrHit] = rlInfo;
235 }
236}
237
238ERightLeft CDCSimHitLookUp::getRLInfo(const CDCHit* ptrHit) const
239{
240 auto itFoundHit = m_rightLeftInfos.find(ptrHit);
241 return itFoundHit == m_rightLeftInfos.end() ? ERightLeft::c_Invalid : itFoundHit->second;
242}
243
244ROOT::Math::XYZVector CDCSimHitLookUp::getRecoPos3D(const CDCHit* ptrHit) const
245{
246 if (not m_ptrMCMap) {
247 B2WARNING("CDCMCMap not set. Cannot find reconstructed position");
248 return ROOT::Math::XYZVector();
249 }
250
251 const CDCMCMap& mcMap = *m_ptrMCMap;
252 const CDCSimHit* ptrSimHit = mcMap.getSimHit(ptrHit);
253
254 if (not ptrSimHit) {
255 B2WARNING("No CDCSimHit related to CDCHit");
256 return ROOT::Math::XYZVector();
257 }
258
259 const CDCSimHit& simHit = *ptrSimHit;
260 return ROOT::Math::XYZVector{simHit.getPosTrack()};
261}
262
263double CDCSimHitLookUp::getDriftLength(const CDCHit* ptrHit) const
264{
265 if (not m_ptrMCMap) {
266 B2WARNING("CDCMCMap not set. Cannot find reconstructed position");
267 return NAN;
268 }
269
270 const CDCMCMap& mcMap = *m_ptrMCMap;
271 const CDCSimHit* ptrSimHit = mcMap.getSimHit(ptrHit);
272
273 if (not ptrSimHit) {
274 B2WARNING("No CDCSimHit related to CDCHit");
275 return NAN;
276 }
277
278 const CDCSimHit& simHit = *ptrSimHit;
279 return simHit.getDriftLength();
280}
281
282ROOT::Math::XYZVector CDCSimHitLookUp::getClosestPrimaryRecoPos3D(const CDCHit* ptrHit) const
283{
284 const CDCSimHit* ptrPrimarySimHit = getClosestPrimarySimHit(ptrHit);
285 if (ptrPrimarySimHit) {
286 const CDCSimHit& primarySimHit = *ptrPrimarySimHit;
287 return ROOT::Math::XYZVector{primarySimHit.getPosTrack()};
288 } else {
289 return getRecoPos3D(ptrHit);
290 }
291}
293{
294 const CDCSimHit* ptrPrimarySimHit = getClosestPrimarySimHit(ptrHit);
295 if (ptrPrimarySimHit) {
296 const CDCSimHit& primarySimHit = *ptrPrimarySimHit;
297 return primarySimHit.getDriftLength();
298 } else {
299 return getDriftLength(ptrHit);
300 }
301}
302
304 const std::vector<CDCWireHit>& wireHits) const
305{
306 if (not ptrHit) return nullptr;
307 ConstVectorRange<CDCWireHit> wireHit{std::equal_range(wireHits.begin(), wireHits.end(), *ptrHit)};
308
309 if (wireHit.empty()) {
310 return nullptr;
311 } else {
312 return &(wireHit.front());
313 }
314}
315
317 const std::vector<CDCWireHit>& wireHits) const
318{
319 ERightLeft rlInfo = getRLInfo(ptrHit);
320 double driftLength = getDriftLength(ptrHit);
321 const CDCWireHit* wireHit = getWireHit(ptrHit, wireHits);
322 B2ASSERT("Could not find CDCWireHit for the requested hit", wireHit);
323 return CDCRLWireHit(wireHit, rlInfo, driftLength, CDCWireHit::c_simpleDriftLengthVariance);
324}
325
327 const std::vector<CDCWireHit>& wireHits) const
328{
329 CDCRLWireHit rlWireHit = getRLWireHit(ptrHit, wireHits);
330 double driftLength = getDriftLength(ptrHit);
331 rlWireHit.setRefDriftLength(driftLength);
332 ROOT::Math::XYZVector recoPos3D = getRecoPos3D(ptrHit);
333 return CDCRecoHit3D(rlWireHit, recoPos3D);
334}
335
338 const std::vector<CDCWireHit>& wireHits) const
339{
340 CDCRLWireHit rlWireHit = getRLWireHit(ptrHit, wireHits);
341 double driftLength = getClosestPrimaryDriftLength(ptrHit);
342 rlWireHit.setRefDriftLength(driftLength);
343 ROOT::Math::XYZVector recoPos3D = getClosestPrimaryRecoPos3D(ptrHit);
344 return CDCRecoHit3D(rlWireHit, recoPos3D);
345}
346
348 const std::vector<CDCWireHit>& wireHits) const
349{
350 return getRecoHit3D(ptrHit, wireHits).getRecoHit2D();
351}
352
355 const std::vector<CDCWireHit>& wireHits) const
356{
357 return getClosestPrimaryRecoHit3D(ptrHit, wireHits).getRecoHit2D();
358}
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
B2Vector3D getPosWire() const
The method to get position on wire.
Definition CDCSimHit.h:198
WireID getWireID() const
Getter for WireID object.
Definition CDCSimHit.h:171
B2Vector3D getPosTrack() const
The method to get position on the track.
Definition CDCSimHit.h:216
double getDriftLength() const
The method to get drift length.
Definition CDCSimHit.h:180
B2Vector3D getMomentum() const
The method to get momentum.
Definition CDCSimHit.h:192
static constexpr const double c_simpleDriftLengthVariance
A default value for the drift length variance if no variance from the drift length translation is ava...
Definition CDCWireHit.h:65
Class representing the sense wire arrangement in the whole of the central drift chamber.
bool arePrimaryNeighbors(const WireID &wireID, const WireID &otherWireID) const
Checks if two wires are primary neighbors.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
static const CDCSimHitLookUp & getSimHitLookUp()
Getter for the singleton instance of the CDCSimHitLookUp.
Class to organize and present the Monte Carlo hit information.
Definition CDCMCMap.h:28
TrackingUtilities::MayBePtr< const CDCSimHit > getSimHit(const CDCHit *hit) const
Seeks the CDCSimHit related to the CDCHit.
Definition CDCMCMap.cc:250
const std::multimap< const CDCHit *, const CDCSimHit * > & getSimHitsByHit() const
Getter for the CDCHit -> CDCSimHit relations.
Definition CDCMCMap.h:134
TrackingUtilities::MayBePtr< const MCParticle > getMCParticle(const CDCHit *hit) const
Seeks the MCParticle related to the CDCHit.
Definition CDCMCMap.cc:270
bool isReassignedSecondary(const CDCSimHit *ptrSimHit) const
Indicates if the CDCSimHit has been reassigned to a primary MCParticle.
Definition CDCMCMap.h:110
auto getSimHits(const MCParticle *mcParticle) const
Getter for the range MCParticle to CDCSimHits relations which come from the given MCParticle.
Definition CDCMCMap.h:98
TrackingUtilities::CDCRecoHit3D getClosestPrimaryRecoHit3D(const CDCHit *ptrHit, const std::vector< TrackingUtilities::CDCWireHit > &wireHits) const
Construct an CDCRecoHit3D from the closest primary CDCSimHit information related to the CDCHit.
void fillRLInfo()
Construct the look up relation for the right left passage information as used in track finding.
std::map< const CDCHit *, TrackingUtilities::MayBePtr< const CDCSimHit > > m_primarySimHits
Memory for the look up relation of close primary CDCSimHits.
static const CDCSimHitLookUp & getInstance()
Getter for the singletone instance.
double getClosestPrimaryDriftLength(const CDCHit *ptrHit) const
Look up the drift length from the primary ionisation to the wire from related simulated hit.
double getDriftLength(const CDCHit *ptrHit) const
Look up the drift length from the primary ionisation to the wire from related simulated hit.
ROOT::Math::XYZVector getClosestPrimaryRecoPos3D(const CDCHit *ptrHit) const
Look up the position of the primary ionisation from the closest primary simulated hit.
void fillPrimarySimHits()
Constructs the relation from reassigned secondary to a close by primary hit from the same MCParticle.
TrackingUtilities::MayBePtr< const CDCSimHit > getClosestPrimarySimHit(const CDCSimHit *ptrSimHit) const
Helper function to find the closest primary hit for the given CDCSimHit from the same MCParticle - nu...
CDCSimHitLookUp(CDCSimHitLookUp &)=delete
Singleton: Delete copy constructor and assignment operator.
TrackingUtilities::CDCRecoHit3D getRecoHit3D(const CDCHit *ptrHit, const std::vector< TrackingUtilities::CDCWireHit > &wireHits) const
Construct an CDCRecoHit3D from the (potential secondary) CDCSimHit information related to the CDCHit.
const CDCMCMap * m_ptrMCMap
Reference to the CDCMCMap to be used in this event.
TrackingUtilities::CDCRecoHit2D getClosestPrimaryRecoHit2D(const CDCHit *ptrHit, const std::vector< TrackingUtilities::CDCWireHit > &wireHits) const
Construct an TrackingUtilities::CDCRecoHit2D from the closest primary CDCSimHit information related t...
const TrackingUtilities::CDCWireHit * getWireHit(const CDCHit *ptrHit, const std::vector< TrackingUtilities::CDCWireHit > &wireHits) const
Retrieve the wire hit the given CDCHit form the given wire hits.
std::map< const CDCHit *, TrackingUtilities::ERightLeft > m_rightLeftInfos
Memory for the look up relation of the right left passage information as defined in tracking.
TrackingUtilities::CDCRecoHit2D getRecoHit2D(const CDCHit *ptrHit, const std::vector< TrackingUtilities::CDCWireHit > &wireHits) const
Construct an TrackingUtilities::CDCRecoHit2D from the (potential secondary) CDCSimHit information rel...
ROOT::Math::XYZVector getDirectionOfFlight(const CDCHit *ptrHit)
Calculate the local direction of flight. If the hit is secondary take the direction of flight from a ...
void fill(const CDCMCMap *ptrMCMap)
Gather the information about the right left passage using the CDCMCMap.
void clear()
Clear all information from the last event.
TrackingUtilities::CDCRLWireHit getRLWireHit(const CDCHit *ptrHit, const std::vector< TrackingUtilities::CDCWireHit > &wireHits) const
Retrieve the wire hit including right left passage information for the given CDCHit form the given wi...
TrackingUtilities::ERightLeft getRLInfo(const CDCHit *ptrHit) const
Look up the Monte Carlo right left passage information for the given hit.
ROOT::Math::XYZVector getRecoPos3D(const CDCHit *ptrHit) const
Look up the position of the primary ionisation from related simulated hit.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
void setRefDriftLength(double driftLength)
Setter for the drift length at the reference position of the wire.
Class representing a two dimensional reconstructed hit in the central drift chamber.
Class representing a three dimensional reconstructed hit.
CDCRecoHit2D getRecoHit2D() const
Constructs a two dimensional reconstructed hit by carrying out the stereo !
Class representing a hit wire in the central drift chamber.
Definition CDCWireHit.h:56
Class to identify a wire inside the CDC.
Definition WireID.h:34
Abstract base class for different kinds of events.