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 <tracking/trackFindingCDC/topology/CDCWireTopology.h>
17 #include <tracking/trackFindingCDC/utilities/Functional.h>
18 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
20 #include <cdc/dataobjects/CDCHit.h>
21 #include <cdc/dataobjects/CDCSimHit.h>
22 #include <mdst/dataobjects/MCParticle.h>
25 using namespace TrackFindingCDC;
36 B2DEBUG(29,
"In CDCMCTrackStore::clear()");
55 B2DEBUG(29,
"In CDCMCTrackStore::fill()");
79 B2DEBUG(28,
"m_inTrackIds.size(): " <<
m_inTrackIds.size());
82 B2DEBUG(28,
"m_nLoops.size(): " <<
m_nLoops.size());
90 B2WARNING(
"CDCMCMap not set. Cannot create tracks");
98 const MCParticle* ptrMCParticle = std::get<const MCParticle* const>(relation);
99 const CDCHit* ptrHit = std::get<const CDCHit*>(relation);
125 ITrackType mcParticleIdx = mcTrackAndMCParticleIdx.first;
128 if (mcTrack.empty())
continue;
133 auto superLayerRanges = adjacent_groupby(mcTrack.begin(), mcTrack.end(), [](
const CDCHit * hit) {
134 return hit->getISuperLayer();
137 std::vector<CDCHitVector> superLayerRuns;
138 for (
const auto& superLayerRange : superLayerRanges) {
139 superLayerRuns.push_back({superLayerRange.begin(), superLayerRange.end()});
142 std::vector<std::vector<CDCHitVector>::iterator> smallSuperLayerRuns;
143 for (
auto itSuperLayerRun = superLayerRuns.begin();
144 itSuperLayerRun != superLayerRuns.end();
146 if (itSuperLayerRun->size() < 3) smallSuperLayerRuns.push_back(itSuperLayerRun);
150 for (
auto itSuperLayerRun : smallSuperLayerRuns) {
151 ISuperLayer iSL = itSuperLayerRun->front()->getISuperLayer();
154 auto itSuperLayerRunBefore = superLayerRuns.end();
155 int hitDistanceBefore = INT_MAX;
156 if (std::distance(superLayerRuns.begin(), itSuperLayerRun) >= 2) {
157 itSuperLayerRunBefore = itSuperLayerRun - 2;
158 if (itSuperLayerRunBefore->front()->getISuperLayer() == iSL) {
159 hitDistanceBefore = (itSuperLayerRunBefore - 1)->size();
161 itSuperLayerRunBefore = superLayerRuns.end();
165 auto itSuperLayerRunAfter = superLayerRuns.end();
166 int hitDistanceAfter = INT_MAX;
167 if (std::distance(itSuperLayerRun, superLayerRuns.end()) > 2) {
168 itSuperLayerRunAfter = itSuperLayerRun + 2;
169 if (itSuperLayerRunAfter->front()->getISuperLayer() == iSL) {
170 hitDistanceAfter = (itSuperLayerRunAfter + 1)->size();
172 itSuperLayerRunAfter = superLayerRuns.end();
176 auto itMergeSuperLayerRun = superLayerRuns.end();
177 bool mergeBefore =
false;
178 if (hitDistanceBefore < hitDistanceAfter) {
179 itMergeSuperLayerRun = itSuperLayerRunBefore;
182 itMergeSuperLayerRun = itSuperLayerRunAfter;
186 if (itMergeSuperLayerRun == superLayerRuns.end())
continue;
187 else if (mergeBefore) {
188 itMergeSuperLayerRun->insert(itMergeSuperLayerRun->end(), itSuperLayerRun->begin(), itSuperLayerRun->end());
189 itSuperLayerRun->clear();
191 itMergeSuperLayerRun->insert(itMergeSuperLayerRun->begin(), itSuperLayerRun->begin(), itSuperLayerRun->end());
192 itSuperLayerRun->clear();
197 erase_remove_if(superLayerRuns,
Size() == 0u);
201 if (lhs.empty() or rhs.empty())
return true;
202 if (lhs.front()->getISuperLayer() != rhs.front()->getISuperLayer())
return false;
203 lhs.insert(lhs.end(), rhs.begin(), rhs.end());
207 erase_unique(superLayerRuns, mergeSameSuperLayer);
210 for (
const CDCHitVector& superLayerRun : superLayerRuns) {
212 auto areNeighbors = [&wireTopology](
const CDCHit * lhs,
const CDCHit * rhs) {
214 WireID rhsWireID(rhs->getISuperLayer(), rhs->getILayer(), rhs->getIWire());
218 lhsWireID == rhsWireID);
221 auto segmentRanges = unique_ranges(superLayerRun.begin(), superLayerRun.end(), areNeighbors);
224 mcSegments.emplace_back(segmentRange.begin(), segmentRange.end());
238 B2WARNING(
"CDCMCMap not set. Cannot sort track");
244 std::stable_sort(mcTrack.begin(), mcTrack.end(),
245 [&simHitLookUp](
const CDCHit * ptrHit,
const CDCHit * ptrOtherHit) ->
bool {
247 const CDCSimHit* ptrSimHit = simHitLookUp.getClosestPrimarySimHit(ptrHit);
248 const CDCSimHit* ptrOtherSimHit = simHitLookUp.getClosestPrimarySimHit(ptrOtherHit);
252 B2FATAL(
"No CDCSimHit for CDCHit");
255 if (not ptrOtherSimHit)
257 B2FATAL(
"No CDCSimHit for CDCHit");
260 double secondaryFlightTime = ptrSimHit->getFlightTime();
261 double otherSecondaryFlightTime = ptrOtherSimHit->getFlightTime();
264 return (secondaryFlightTime < std::fmin(INFINITY, otherSecondaryFlightTime));
274 void CDCMCTrackStore::fillInTrackId()
277 for (
const std::pair<ITrackType, CDCHitVector> mcTrackAndMCParticleIdx : getMCTracksByMCParticleIdx()) {
279 const CDCHitVector& mcTrack = mcTrackAndMCParticleIdx.second;
283 for (
const CDCHit* ptrHit : mcTrack) {
285 m_inTrackIds[ptrHit] = iHit;
291 void CDCMCTrackStore::fillInTrackSegmentId()
293 for (
const std::pair<ITrackType, std::vector<CDCHitVector> > mcSegmentsAndMCParticleIdx : getMCSegmentsByMCParticleIdx()) {
294 const std::vector<CDCHitVector>& mcSegments = mcSegmentsAndMCParticleIdx.second;
299 for (
const CDCHit* ptrHit : mcSegment) {
301 m_inTrackSegmentIds[ptrHit] = iSegment;
308 void CDCMCTrackStore::fillNLoopsAndNPassedSuperLayers()
311 for (
const std::pair<ITrackType, std::vector<CDCHitVector> > mcSegmentsAndMCParticleIdx : getMCSegmentsByMCParticleIdx()) {
312 const std::vector<CDCHitVector>& mcSegments = mcSegmentsAndMCParticleIdx.second;
315 int nPassedSuperLayers = 0;
319 if (ptrLastMCSegment and changedSuperLayer(*ptrLastMCSegment, mcSegment)) {
320 ++nPassedSuperLayers;
324 if (ptrLastMCSegment->front()->getISuperLayer() == 0 and
325 mcSegment.front()->getISuperLayer() == 0) {
330 for (
const CDCHit* ptrHit : mcSegment) {
331 m_nPassedSuperLayers[ptrHit] = nPassedSuperLayers;
332 m_nLoops[ptrHit] = nLoops;
335 ptrLastMCSegment = &mcSegment;
344 const CDCHit* ptrHit = mcSegment.front();
345 const CDCHit* ptrNextHit = nextMCSegment.front();
350 const CDCHit& hit = *ptrHit;
351 const CDCHit& nextHit = *ptrNextHit;
355 }
else if (hit.getISuperLayer() == 0) {
364 if (pos.dotXY(nextPos) < 0)
return true;
365 if ((nextPos - pos).dotXY(nextMom) < 0)
return true;
366 if ((nextPos - pos).dotXY(mom) < 0)
return true;
376 Index CDCMCTrackStore::getInTrackId(
const CDCHit* ptrHit)
const
379 auto itFoundHit = m_inTrackIds.find(ptrHit);
380 return itFoundHit == m_inTrackIds.end() ? c_InvalidIndex : itFoundHit->second;
386 Index CDCMCTrackStore::getInTrackSegmentId(
const CDCHit* ptrHit)
const
389 auto itFoundHit = m_inTrackSegmentIds.find(ptrHit);
390 return itFoundHit == m_inTrackSegmentIds.end() ? c_InvalidIndex : itFoundHit->second;
395 Index CDCMCTrackStore::getNPassedSuperLayers(
const CDCHit* ptrHit)
const
398 auto itFoundHit = m_nPassedSuperLayers.find(ptrHit);
399 return itFoundHit == m_nPassedSuperLayers.end() ? c_InvalidIndex : itFoundHit->second;
403 Index CDCMCTrackStore::getNLoops(
const CDCHit* ptrHit)
const
406 auto itFoundHit = m_nLoops.find(ptrHit);
407 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.
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 singletone 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.
Class to organize and present the monte carlo hit information.
std::map< const CDCHit *, int > m_inTrackIds
Look up table for index of the hit within its track.
std::map< ITrackType, std::vector< CDCHitVector > > m_mcSegmentsByMCParticleIdx
The memory for the segments made of CDCHits sorted for the time of flight and assoziated 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.
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 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.
std::map< const CDCHit *, int > m_nLoops
Look up table for the number of loops the particle traversed before making the individual hit.
void clear()
Clear all Monte Carlo hits.
void arrangeMCTrack(CDCHitVector &mcTrack) const
Sorts the given track for the FlightTime of the assoziated CDCSimHits.
void fillInTrackId()
Fill the look up table for the in track index of each hit.
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.
std::map< ITrackType, CDCHitVector > m_mcTracksByMCParticleIdx
The memory for the tracks made of CDCHits sorted for the time of flight and assoziated to the Monte C...
Singletone class to gather local information about the hits.
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 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.
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 pair of iterators usable with the range base for loop.
A three dimensional vector.
Class to identify a wire inside the CDC.
Abstract base class for different kinds of events.
Functor to get the .size() from an abitrary objects.