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