9#include <tracking/trackFindingCDC/mclookup/CDCMCTrackStore.h>
11#include <tracking/trackFindingCDC/mclookup/CDCSimHitLookUp.h>
12#include <tracking/trackFindingCDC/mclookup/CDCMCMap.h>
13#include <tracking/trackFindingCDC/mclookup/CDCMCManager.h>
15#include <cdc/topology/CDCWireTopology.h>
17#include <tracking/trackingUtilities/utilities/Functional.h>
18#include <tracking/trackingUtilities/utilities/Algorithms.h>
19#include <tracking/trackingUtilities/geometry/Vector3D.h>
21#include <cdc/dataobjects/CDCHit.h>
22#include <cdc/dataobjects/CDCSimHit.h>
23#include <mdst/dataobjects/MCParticle.h>
27using namespace TrackFindingCDC;
28using namespace TrackingUtilities;
39 B2DEBUG(29,
"In CDCMCTrackStore::clear()");
58 B2DEBUG(29,
"In CDCMCTrackStore::fill()");
82 B2DEBUG(28,
"m_inTrackIds.size(): " <<
m_inTrackIds.size());
85 B2DEBUG(28,
"m_nLoops.size(): " <<
m_nLoops.size());
93 B2WARNING(
"CDCMCMap not set. Cannot create tracks");
101 const MCParticle* ptrMCParticle = std::get<const MCParticle* const>(relation);
102 const CDCHit* ptrHit = std::get<const CDCHit*>(relation);
128 ITrackType mcParticleIdx = mcTrackAndMCParticleIdx.first;
131 if (mcTrack.empty())
continue;
136 auto superLayerRanges = adjacent_groupby(mcTrack.begin(), mcTrack.end(), [](
const CDCHit * hit) {
137 return hit->getISuperLayer();
140 std::vector<CDCHitVector> superLayerRuns;
141 for (
const auto& superLayerRange : superLayerRanges) {
142 superLayerRuns.push_back({superLayerRange.begin(), superLayerRange.end()});
145 std::vector<std::vector<CDCHitVector>::iterator> smallSuperLayerRuns;
146 for (
auto itSuperLayerRun = superLayerRuns.begin();
147 itSuperLayerRun != superLayerRuns.end();
149 if (itSuperLayerRun->size() < 3) smallSuperLayerRuns.push_back(itSuperLayerRun);
153 for (
auto itSuperLayerRun : smallSuperLayerRuns) {
154 ISuperLayer iSL = itSuperLayerRun->front()->getISuperLayer();
157 auto itSuperLayerRunBefore = superLayerRuns.end();
158 int hitDistanceBefore = INT_MAX;
159 if (std::distance(superLayerRuns.begin(), itSuperLayerRun) >= 2) {
160 itSuperLayerRunBefore = itSuperLayerRun - 2;
161 if (itSuperLayerRunBefore->front()->getISuperLayer() == iSL) {
162 hitDistanceBefore = (itSuperLayerRunBefore - 1)->size();
164 itSuperLayerRunBefore = superLayerRuns.end();
168 auto itSuperLayerRunAfter = superLayerRuns.end();
169 int hitDistanceAfter = INT_MAX;
170 if (std::distance(itSuperLayerRun, superLayerRuns.end()) > 2) {
171 itSuperLayerRunAfter = itSuperLayerRun + 2;
172 if (itSuperLayerRunAfter->front()->getISuperLayer() == iSL) {
173 hitDistanceAfter = (itSuperLayerRunAfter + 1)->size();
175 itSuperLayerRunAfter = superLayerRuns.end();
179 auto itMergeSuperLayerRun = superLayerRuns.end();
180 bool mergeBefore =
false;
181 if (hitDistanceBefore < hitDistanceAfter) {
182 itMergeSuperLayerRun = itSuperLayerRunBefore;
185 itMergeSuperLayerRun = itSuperLayerRunAfter;
189 if (itMergeSuperLayerRun == superLayerRuns.end())
continue;
190 else if (mergeBefore) {
191 itMergeSuperLayerRun->insert(itMergeSuperLayerRun->end(), itSuperLayerRun->begin(), itSuperLayerRun->end());
192 itSuperLayerRun->clear();
194 itMergeSuperLayerRun->insert(itMergeSuperLayerRun->begin(), itSuperLayerRun->begin(), itSuperLayerRun->end());
195 itSuperLayerRun->clear();
200 erase_remove_if(superLayerRuns,
Size() == 0u);
204 if (lhs.empty() or rhs.empty())
return true;
205 if (lhs.front()->getISuperLayer() != rhs.front()->getISuperLayer())
return false;
206 lhs.insert(lhs.end(), rhs.begin(), rhs.end());
210 erase_unique(superLayerRuns, mergeSameSuperLayer);
213 for (
const CDCHitVector& superLayerRun : superLayerRuns) {
215 auto areNeighbors = [&wireTopology](
const CDCHit * lhs,
const CDCHit * rhs) {
217 WireID rhsWireID(rhs->getISuperLayer(), rhs->getILayer(), rhs->getIWire());
221 lhsWireID == rhsWireID);
224 auto segmentRanges = unique_ranges(superLayerRun.begin(), superLayerRun.end(), areNeighbors);
226 for (
const ConstVectorRange<const CDCHit*>& segmentRange : segmentRanges) {
227 mcSegments.emplace_back(segmentRange.begin(), segmentRange.end());
241 B2WARNING(
"CDCMCMap not set. Cannot sort track");
247 std::stable_sort(mcTrack.begin(), mcTrack.end(),
248 [&simHitLookUp](
const CDCHit * ptrHit,
const CDCHit * ptrOtherHit) ->
bool {
250 const CDCSimHit* ptrSimHit = simHitLookUp.getClosestPrimarySimHit(ptrHit);
251 const CDCSimHit* ptrOtherSimHit = simHitLookUp.getClosestPrimarySimHit(ptrOtherHit);
255 B2FATAL(
"No CDCSimHit for CDCHit");
258 if (not ptrOtherSimHit)
260 B2FATAL(
"No CDCSimHit for CDCHit");
263 double secondaryFlightTime = ptrSimHit->getFlightTime();
264 double otherSecondaryFlightTime = ptrOtherSimHit->getFlightTime();
267 return (secondaryFlightTime < std::fmin(INFINITY, otherSecondaryFlightTime));
282 const CDCHitVector& mcTrack = mcTrackAndMCParticleIdx.second;
286 for (
const CDCHit* ptrHit : mcTrack) {
297 const std::vector<CDCHitVector>& mcSegments = mcSegmentsAndMCParticleIdx.second;
302 for (
const CDCHit* ptrHit : mcSegment) {
315 const std::vector<CDCHitVector>& mcSegments = mcSegmentsAndMCParticleIdx.second;
318 int nPassedSuperLayers = 0;
323 ++nPassedSuperLayers;
327 if (ptrLastMCSegment->front()->getISuperLayer() == 0 and
328 mcSegment.front()->getISuperLayer() == 0) {
333 for (
const CDCHit* ptrHit : mcSegment) {
338 ptrLastMCSegment = &mcSegment;
347 const CDCHit* ptrHit = mcSegment.front();
348 const CDCHit* ptrNextHit = nextMCSegment.front();
353 const CDCHit& hit = *ptrHit;
354 const CDCHit& nextHit = *ptrNextHit;
367 if (pos.dotXY(nextPos) < 0)
return true;
368 if ((nextPos - pos).dotXY(nextMom) < 0)
return true;
369 if ((nextPos - pos).dotXY(mom) < 0)
return true;
383 return itFoundHit ==
m_inTrackIds.end() ? c_InvalidIndex : itFoundHit->second;
409 auto itFoundHit =
m_nLoops.find(ptrHit);
410 return itFoundHit ==
m_nLoops.end() ? c_InvalidIndex : itFoundHit->second;
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
unsigned short getIWire() const
Getter for iWire.
unsigned short getISuperLayer() const
Getter for iSuperLayer.
unsigned short getILayer() const
Getter for iLayer.
B2Vector3D getPosTrack() const
The method to get position on the track.
B2Vector3D getMomentum() const
The method to get momentum.
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.
bool areSeconaryNeighbors(const WireID &wireID, const WireID &otherWireID) const
Checks if two wires are secondary neighbors.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
A Class to store the Monte Carlo particle information.
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
static const CDCMCTrackStore & getMCTrackStore()
Getter for the singleton instance of the CDCMCTrackStore.
Class to organize and present the Monte Carlo hit information.
bool isBackground(const CDCSimHit *simHit) const
Indicates if the CDCSimHit is considered background.
const std::multimap< const MCParticle *, const CDCHit * > & getHitsByMCParticle() const
Getter for the MCParticle -> CDCHit relations.
std::map< const CDCHit *, int > m_inTrackIds
Look up table for index of the hit within its track.
TrackingUtilities::Index getNPassedSuperLayers(const CDCHit *ptrHit) const
Getter for the number of super layers traversed until this hit.
std::map< ITrackType, std::vector< CDCHitVector > > m_mcSegmentsByMCParticleIdx
The memory for the segments made of CDCHits sorted for the time of flight and associated to the Monte...
void fillMCTracks()
Construct the tracks by grouping the hits by the mc particle id and sorted them for the FlightTime of...
void fillNLoopsAndNPassedSuperLayers()
Fill the look up table of the number of traversed super layers until each hit.
static const CDCMCTrackStore & getInstance()
Getter for the singletone instance.
TrackingUtilities::Index getInTrackSegmentId(const CDCHit *ptrHit) const
Getter for the index of the segment of the hit within its track.
std::vector< const CDCHit * > CDCHitVector
Type for an ordered sequence of pointers to the CDCHit.
const CDCSimHitLookUp * m_ptrSimHitLookUp
Reference to the CDCSimHit look up for additional information about related primary sim hits.
std::map< const CDCHit *, int > m_nPassedSuperLayers
Look up table for the number of super layers the particle traversed before making the individual hit.
const std::map< ITrackType, Belle2::TrackFindingCDC::CDCMCTrackStore::CDCHitVector > & getMCTracksByMCParticleIdx() const
Getter for the stored Monte Carlo tracks ordered by their Monte Carlo Id.
const CDCMCMap * m_ptrMCMap
Reference to the MC map of the current event.
void fill(const CDCMCMap *ptrMCMap, const CDCSimHitLookUp *ptrSimHitLookUp)
Fill the store with the tracks from Monte Carlo information.
TrackingUtilities::Index getNLoops(const CDCHit *ptrHit) const
Getter for the number of traversed loops until this hit.
std::map< const CDCHit *, int > m_nLoops
Look up table for the number of loops the particle traversed before making the individual hit.
const std::map< ITrackType, std::vector< Belle2::TrackFindingCDC::CDCMCTrackStore::CDCHitVector > > & getMCSegmentsByMCParticleIdx() const
Getter for the stored Monte Carlo segments ordered by their Monte Carlo Id.
void clear()
Clear all Monte Carlo hits.
void arrangeMCTrack(CDCHitVector &mcTrack) const
Sorts the given track for the FlightTime of the associated CDCSimHits.
void fillInTrackId()
Fill the look up table for the in track index of each hit.
CDCMCTrackStore()=default
Default constructor - for cppcheck.
TrackingUtilities::Index getInTrackId(const CDCHit *ptrHit) const
Getter for the index of the hit within its track.
void fillMCSegments()
Construct the segments by dividing the mc tracks in to disconnected parts and sorted them for the Fli...
std::map< const CDCHit *, int > m_inTrackSegmentIds
Look up table for index of the segment of the hits within their respective tracks.
void fillInTrackSegmentId()
Fill the look up table for the in track segment index of each hit.
bool changedSuperLayer(const CDCHitVector &mcSegment, const CDCHitVector &nextMCSegment) const
Helper function to decide whether the number of passed superlayers changed from one segment to the ne...
std::map< ITrackType, CDCHitVector > m_mcTracksByMCParticleIdx
The memory for the tracks made of CDCHits sorted for the time of flight and associated to the Monte C...
Singletone class to gather local information about the hits.
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...
Class to identify a wire inside the CDC.
HepGeom::Vector3D< double > Vector3D
3D Vector
signed short ISuperLayer
The type of the layer and superlayer ids.
Abstract base class for different kinds of events.
Functor to get the .size() from an arbitrary objects.