3 #define _USE_MATH_DEFINES 11 #include "FairLogger.h" 44 output <<
"Triplet: ";
46 output << hit->GetTubeID() <<
"(" << hit->GetX() <<
"," << hit->GetY() <<
") /";
56 std::vector<std::string> detID_Names{
"MVD_Pixel",
"MVD_Strip",
"STT",
"GEM",
"NOTDEFINED"};
61 void AddHits(
detID detector, std::vector<FairHit *> data) { fHits[detector] = data; }
63 void AddHits(std::vector<PndSttHit *> sttHits) { fHits[STT].insert(fHits[STT].end(), sttHits.begin(), sttHits.end()); }
67 if (fHits.count(detector) == 0) {
70 if (std::find(fHits[detector].begin(), fHits[detector].end(), data) == fHits[detector].end()) {
71 fHits[detector].push_back(data);
75 int GetNHits() {
return fHits[MVDpixel].size() + fHits[MVDstrip].size() + fHits[STT].size() + fHits[
GEM].size(); }
77 TVector2
HitOnTrack(FairHit *hit) {
return TVector2(hit->GetX() - fTrack.X(), hit->GetY() - fTrack.Y()); }
81 std::vector<FairHit *> sttHits = fHits[STT];
82 if (sttHits.size() > 2) {
85 std::sort(sttHits.begin(), sttHits.end(), [](FairHit *first, FairHit *second) {
return (*(static_cast<PndSttHit *>(first)) < *(
static_cast<PndSttHit *
>(second))); });
86 TVector2 firstHit(HitOnTrack(sttHits.front()));
87 TVector2 secondHit(HitOnTrack(sttHits.back()));
88 if (firstHit.DeltaPhi(secondHit) < 0) {
97 std::sort(fHits[detector].begin(), fHits[detector].end(), [&](FairHit *a, FairHit *b) {
98 double phi_a = HitOnTrack(a).DeltaPhi(firstHit);
99 double phi_b = HitOnTrack(b).DeltaPhi(firstHit);
105 return (phi_a > phi_b);
108 std::sort(fHits[detector].begin(), fHits[detector].end(), [&](FairHit *a, FairHit *b) {
109 double phi_a = HitOnTrack(a).DeltaPhi(firstHit);
110 double phi_b = HitOnTrack(b).DeltaPhi(firstHit);
115 return (phi_a < phi_b);
122 std::vector<FairHit *> sttHits = fHits[STT];
123 if (sttHits.size() > 2) {
127 std::sort(sttHits.begin(), sttHits.end(), [](FairHit *first, FairHit *second) {
return (*(static_cast<PndSttHit *>(first)) < *(
static_cast<PndSttHit *
>(second))); });
128 std::vector<FairHit *> possibleFirstHits;
130 for(
auto hit : sttHits){
131 if (fGeometryMap->
GetRow(static_cast<PndSttHit *>(hit)->GetTubeID()) <= minRow) {
132 minRow = fGeometryMap->
GetRow(static_cast<PndSttHit *>(hit)->GetTubeID());
133 possibleFirstHits.push_back(hit);
139 firstHit = HitOnTrack(possibleFirstHits.back());
141 firstHit = HitOnTrack(possibleFirstHits.front());
143 SortHits(firstHit, STT);
149 std::vector<FairHit *> mvdPixelHits = fHits[MVDpixel];
150 std::vector<FairHit *> mvdStripHits = fHits[MVDstrip];
151 std::vector<FairHit *> sttHits = fHits[STT];
152 std::vector<FairHit *> gemHits = fHits[
GEM];
154 if (mvdPixelHits.size() > 0) {
155 double dSquare = 100000.;
156 FairHit *first =
nullptr;
157 for (
auto hit : mvdPixelHits) {
158 if (((hit->GetX() * hit->GetX()) + (hit->GetY() * hit->GetY() + (hit->GetZ() * hit->GetZ()))) < dSquare) {
159 dSquare = ((hit->GetX() * hit->GetX()) + (hit->GetY() * hit->GetY()) + (hit->GetZ() * hit->GetZ()));
164 }
else if (mvdStripHits.size() > 0) {
165 double dSquare = 100000.;
166 FairHit *first =
nullptr;
167 for (
auto hit : mvdStripHits) {
168 if (((hit->GetX() * hit->GetX()) + (hit->GetY() * hit->GetY() + (hit->GetZ() * hit->GetZ()))) < dSquare) {
169 dSquare = ((hit->GetX() * hit->GetX()) + (hit->GetY() * hit->GetY()) + (hit->GetZ() * hit->GetZ()));
175 }
else if (sttHits.size() > 0) {
176 return sttHits.front();
177 }
else if (gemHits.size() > 0) {
178 double dSquare = 100000.;
179 FairHit *first =
nullptr;
180 for (
auto hit : gemHits) {
181 if (((hit->GetX() * hit->GetX()) + (hit->GetY() * hit->GetY())) < dSquare) {
182 dSquare = ((hit->GetX() * hit->GetX()) + (hit->GetY() * hit->GetY()));
193 std::vector<FairHit *> sttHits = fHits[STT];
195 if (sttHits.size() > 2) {
196 FairHit *first = GetFirstHit(fGeometryMap);
198 TVector2 firstHit(HitOnTrack(first));
199 TVector2 secondHit(HitOnTrack(sttHits.back()));
200 bool hasChanged =
false;
201 if (firstHit.DeltaPhi(secondHit) < 0 && fClockwise) {
204 }
else if (firstHit.DeltaPhi(secondHit) >= 0 && !fClockwise) {
210 SortHits(firstHit, MVDpixel);
211 SortHits(firstHit, MVDstrip);
212 SortHits(firstHit, STT);
213 SortHits(firstHit,
GEM);
214 fAllHits.insert(fAllHits.end(), fHits[MVDpixel].begin(), fHits[MVDpixel].end());
215 fAllHits.insert(fAllHits.end(), fHits[MVDstrip].begin(), fHits[MVDstrip].end());
216 fAllHits.insert(fAllHits.end(), fHits[STT].begin(), fHits[STT].end());
217 fAllHits.insert(fAllHits.end(), fHits[
GEM].begin(), fHits[
GEM].end());
219 SortHits(firstHit, MVDpixel);
220 SortHits(firstHit, MVDstrip);
221 fAllHits.insert(fAllHits.end(), fHits[MVDpixel].begin(), fHits[MVDpixel].end());
222 fAllHits.insert(fAllHits.end(), fHits[MVDstrip].begin(), fHits[MVDstrip].end());
223 fAllHits.insert(fAllHits.end(), fHits[STT].begin(), fHits[STT].end());
224 SortHits(firstHit,
GEM);
225 fAllHits.insert(fAllHits.end(), fHits[
GEM].begin(), fHits[
GEM].end());
232 output <<
"Track x/y/r " << t.
fTrack.X() <<
"/" << t.
fTrack.Y() <<
"/" << t.
fTrack.Z() <<
" ";
236 if (t.
fHits.count(TripletSolution::detID::MVDpixel) > 0) {
237 output << t.
detID_Names.at(TripletSolution::detID::MVDpixel) <<
" : ";
238 for (
auto hit : t.
fHits.at(TripletSolution::detID::MVDpixel)) {
239 output << hit->GetEntryNr() <<
"/";
243 if (t.
fHits.count(TripletSolution::detID::MVDstrip) > 0) {
244 output << t.
detID_Names.at(TripletSolution::detID::MVDstrip) <<
" : ";
245 for (
auto hit : t.
fHits.at(TripletSolution::detID::MVDstrip)) {
246 output << hit->GetEntryNr() <<
"/";
250 if (t.
fHits.count(TripletSolution::detID::STT) > 0) {
251 output << t.
detID_Names.at(TripletSolution::detID::STT) <<
" : ";
252 for (
auto hit : t.
fHits.at(TripletSolution::detID::STT)) {
261 output << hit->GetEntryNr() <<
"/";
272 std::map<detID, std::vector<FairHit *>>
fHits;
274 double fMeanSquare = 1000000.;
275 bool fClockwise =
true;
286 fMidRow.insert(fMidRow.end(), right.
fMidRow.begin(), right.
fMidRow.end());
287 fLastRow.insert(fLastRow.end(), right.
fLastRow.begin(), right.
fLastRow.end());
294 output <<
"FirstRow: ";
295 std::for_each(t.
fFirstRow.begin(), t.
fFirstRow.end(), [](
PndSttHit *hit) { std::cout << hit->GetTubeID() <<
"(" << hit->GetX() <<
"," << hit->GetY() <<
") /"; });
297 output <<
"MidRow: ";
298 std::for_each(t.
fMidRow.begin(), t.
fMidRow.end(), [](
PndSttHit *hit) { std::cout << hit->GetTubeID() <<
"(" << hit->GetX() <<
"," << hit->GetY() <<
") /"; });
300 output <<
"LastRow: ";
301 std::for_each(t.
fLastRow.begin(), t.
fLastRow.end(), [](
PndSttHit *hit) { std::cout << hit->GetTubeID() <<
"(" << hit->GetX() <<
"," << hit->GetY() <<
") /"; });
316 fMapCAToMidTube.clear();
317 fMapCAToOuterTube.clear();
318 fMapInnerTubeToCA.clear();
319 fMapMidTubeToCA.clear();
332 std::map<int, std::vector<PndSttHit *>> result;
334 for (
auto myHit : hits) {
335 auto it = std::find_if(result[fGeometryMap->
GetRow(myHit->GetTubeID())].begin(), result[fGeometryMap->
GetRow(myHit->GetTubeID())].end(),
336 [&myHit](
const PndSttHit *hit) {
return myHit->GetTubeID() == hit->GetTubeID(); });
337 if (it == result[fGeometryMap->
GetRow(myHit->GetTubeID())].end()) {
338 result[fGeometryMap->
GetRow(myHit->GetTubeID())].push_back(myHit);
339 fAllHitsCounter += 1;
341 if ((*it)->GetTimeStamp() > myHit->GetTimeStamp())
342 result[fGeometryMap->
GetRow(myHit->GetTubeID())][it - result[fGeometryMap->
GetRow(myHit->GetTubeID())].begin()] = myHit;
353 std::map<int, std::vector<std::vector<PndSttHit *>>>
358 fIsStrongCurling =
false;
360 std::map<int, std::vector<std::vector<PndSttHit *>>> result;
361 std::map<int, std::vector<PndSttHit *>> tubesByRow = GetAllTubesByRow(hits, fGeometryMap, fAllHitsCounter);
365 for (
auto tubes : tubesByRow) {
366 std::sort(tubes.second.begin(), tubes.second.end(), [](
PndSttHit *first,
PndSttHit *second) {
return (first->
GetTubeID() < second->GetTubeID()); });
367 std::vector<PndSttHit *> group;
369 if (tubes.second.size() > 0)
370 oldTubeId = tubes.second[0]->GetTubeID();
371 std::vector<std::vector<PndSttHit *>> rowGroups;
373 for (
auto sttHit : tubes.second) {
374 if (
TMath::Abs(sttHit->GetTubeID() - oldTubeId) > 1) {
375 if (group.size() > 5 && (tubes.first != tubesByRow.rbegin()->first)) {
378 rowGroups.push_back(group);
381 group.push_back(sttHit);
382 oldTubeId = sttHit->GetTubeID();
384 rowGroups.push_back(group);
386 if (group.size() > 5 && (tubes.first != tubesByRow.rbegin()->first)) {
391 result[tubes.first] = (rowGroups);
393 if (result[tubes.first].size() > 5)
394 fIsStrongCurling =
true;
398 fIsStrongCurling =
true;
416 for (
auto InnerSttHit : triplets.
fFirstRow) {
417 auto CAId_it = fMapHitstoCATracklet.find(InnerSttHit->GetEntryNr());
419 if (CAId_it != fMapHitstoCATracklet.end()) {
421 FairLink CALink = InnerSttHit->GetEntryNr();
425 for (
auto MidSttHit : triplets.
fMidRow) {
426 auto CAId_it = fMapHitstoCATracklet.find(MidSttHit->GetEntryNr());
428 if (CAId_it != fMapHitstoCATracklet.end()) {
430 FairLink CALink = MidSttHit->GetEntryNr();
435 for (
auto OuterSttHit : triplets.
fLastRow) {
436 auto CAId_it = fMapHitstoCATracklet.find(OuterSttHit->GetEntryNr());
438 if (CAId_it != fMapHitstoCATracklet.end()) {
440 FairLink CALink = OuterSttHit->GetEntryNr();
454 PndSttGeometryMap *fGeometryMap,
double &fMinDistance,
bool &fWithCombiReduction)
457 std::vector<Triplet> result;
458 if (fWithCombiReduction) {
459 ReductionMaps maps = CreateMaps(triplets, fMapHitstoCATracklet);
461 std::vector<int> RemovedTubeIdsLast;
462 RemovedTubeIdsLast.clear();
463 std::vector<int> RemovedTubeIdsMid;
464 RemovedTubeIdsMid.clear();
466 LOG(debug) <<
"FirstRow: ";
467 std::for_each(triplets.
fFirstRow.begin(), triplets.
fFirstRow.end(), [](
PndSttHit *hit) { LOG(debug) << hit->GetEntryNr() <<
"/"; });
468 LOG(debug) <<
"iTube: " << iTube->GetEntryNr() <<
" has tubeId: " << iTube->
GetTubeID() <<
" (" << iTube->GetX() <<
"," << iTube->GetY() <<
")";
469 LOG(debug) <<
"first hit " << *iTube;
472 fMapHitstoCATracklet.find(iTube->GetEntryNr()) == fMapHitstoCATracklet.end()) {
474 for (
auto mTube : triplets.
fMidRow) {
476 if (iTube->
GetTubeID() == mTube->GetTubeID() || std::find(RemovedTubeIdsMid.begin(), RemovedTubeIdsMid.end(), mTube->GetTubeID()) !=
477 RemovedTubeIdsMid.end())
480 LOG(debug) <<
"mid hit " << *mTube;
483 fMapHitstoCATracklet.find(mTube->GetEntryNr()) == fMapHitstoCATracklet.end()) {
486 for (
auto oTube : triplets.
fLastRow) {
487 if (mTube->GetTubeID() == oTube->GetTubeID() || std::find(RemovedTubeIdsLast.begin(), RemovedTubeIdsLast.end(), oTube->GetTubeID()) !=
488 RemovedTubeIdsLast.end())
491 LOG(debug) <<
"last hit " << *oTube;
492 if (
sqrt((iTube->GetX() - oTube->GetX()) * (iTube->GetX() - oTube->GetX()) + (iTube->GetY() - oTube->GetY()) * (iTube->GetY() - oTube->GetY())) < fMinDistance)
494 Triplet t{iTube, mTube, oTube};
500 if (mTube->GetTubeID() == connectedOuterTube->
GetTubeID()) {
508 connectedOuterTube = OuterSttHit;
513 LOG(debug) << *mTube <<
"," << *connectedOuterTube;
515 if (mTube->GetTubeID() == connectedOuterTube->
GetTubeID()) {
516 LOG(debug) <<
"mTube == connectedOuterTube";
519 LOG(debug) <<
"last hit connected" << *connectedOuterTube;
521 if (
sqrt((iTube->GetX() - connectedOuterTube->GetX()) * (iTube->GetX() - connectedOuterTube->GetX()) +
522 (iTube->GetY() - connectedOuterTube->GetY()) * (iTube->GetY() - connectedOuterTube->GetY())) < fMinDistance)
525 Triplet t{iTube, mTube, connectedOuterTube};
527 RemovedTubeIdsLast.push_back(connectedOuterTube->GetTubeID());
537 for (
int i = trackCand_temp.
GetNHits() / 2;
i >= 0;
i--) {
542 connectedMidTube = MidSttHit;
551 LOG(debug) <<
"mid hit connected " << *connectedMidTube;
554 LOG(debug) <<
"mid tube has no connection to outer tube ";
556 for (
auto oTube : triplets.
fLastRow) {
557 LOG(debug) <<
"outer hit " << *oTube;
559 if (oTube->GetTubeID() == connectedMidTube->
GetTubeID() ||
560 std::find(RemovedTubeIdsLast.begin(), RemovedTubeIdsLast.end(), oTube->GetTubeID()) != RemovedTubeIdsLast.end())
563 if (
sqrt((iTube->GetX() - oTube->GetX()) * (iTube->GetX() - oTube->GetX()) + (iTube->GetY() - oTube->GetY()) * (iTube->GetY() - oTube->GetY())) < fMinDistance)
566 Triplet t{iTube, connectedMidTube, oTube};
572 LOG(debug) <<
"mid tube has a connection to outer tube ";
573 LOG(debug) <<
"outer hit connected " << *connectedOuterTube;
578 for (
int i = trackCand_temp.
GetNHits() - 1;
i >= 0;
i--) {
581 LOG(debug) <<
"try outer hit " << *OuterSttHit;
583 connectedOuterTube = OuterSttHit;
591 LOG(debug) <<
"outer hit connected " << *connectedOuterTube;
593 if (
sqrt((iTube->GetX() - connectedOuterTube->GetX()) * (iTube->GetX() - connectedOuterTube->GetX()) +
594 (iTube->GetY() - connectedOuterTube->GetY()) * (iTube->GetY() - connectedOuterTube->GetY())) < fMinDistance)
597 Triplet t{iTube, connectedMidTube, connectedOuterTube};
599 RemovedTubeIdsLast.push_back(connectedOuterTube->GetTubeID());
601 RemovedTubeIdsMid.push_back(connectedMidTube->
GetTubeID());
606 for (
auto mTube : triplets.
fMidRow) {
609 for (
auto oTube : triplets.
fLastRow) {
610 if (iTube->GetTubeID() == mTube->GetTubeID() ||
611 mTube->GetTubeID() == oTube->GetTubeID())
614 if (
sqrt((iTube->GetX() - oTube->GetX()) * (iTube->GetX() - oTube->GetX()) + (iTube->GetY() - oTube->GetY()) * (iTube->GetY() - oTube->GetY())) < fMinDistance)
616 Triplet t{iTube, mTube, oTube};
635 auto sol = std::find_if(solutions.begin(), solutions.end(), [&](
TripletSolution &sol) {
637 auto first = std::find_if(sol.fHits[TripletSolution::detID::STT].begin(), sol.fHits[TripletSolution::detID::STT].end(),
638 [&](FairHit *hit) {
return (((
PndSttHit *)hit)->GetTubeID() == trip->GetTubeID()); });
639 if (first == sol.fHits[TripletSolution::detID::STT].end()) {
645 if (sol != solutions.end())
660 std::vector<TripletSolution> result;
661 std::vector<double *> tmpPoints(3);
664 double *pVar =
new double[4];
668 pVar[3] = (triplet.
fTripletHits[k]->GetIsochroneError());
671 double *apolloniusCircles =
new double[6 * 8];
678 for (
int m = 0;
m < 3;
m++) {
679 delete[] tmpPoints[
m];
682 for (
int solutionIndex = 0; solutionIndex < 8; solutionIndex++) {
685 if (apolloniusCircles[(solutionIndex * 6) + 0] == 0 && apolloniusCircles[(solutionIndex * 6) + 1] == 0 && apolloniusCircles[(solutionIndex * 6) + 2] == 0)
689 else if ((!isnan(apolloniusCircles[(solutionIndex * 6) + 0]) && apolloniusCircles[(solutionIndex * 6) + 2] != 0) ||
690 (apolloniusCircles[(solutionIndex * 6) + 0] != 0 && apolloniusCircles[(solutionIndex * 6) + 1] != 0 && apolloniusCircles[(solutionIndex * 6) + 2] != 0)) {
692 TVector3 apollonius{apolloniusCircles[(solutionIndex * 6) + 0], apolloniusCircles[(solutionIndex * 6) + 1],
TMath::Abs(apolloniusCircles[(solutionIndex * 6) + 2])};
707 LOG(debug) << solution;
708 result.push_back(solution);
710 }
else if (!isnan(apolloniusCircles[(solutionIndex * 6) + 0]) && !isnan(apolloniusCircles[(solutionIndex * 6) + 1]) && apolloniusCircles[(solutionIndex * 6) + 2] == 0) {
713 double rMax = 100 / (0.3 * 2) * 5;
716 double mInverse = -1 / apolloniusCircles[(solutionIndex * 6) + 0];
717 double b = tmpPoints[0][1] - tmpPoints[0][0] * mInverse;
719 double intersectionPointX = (b - apolloniusCircles[(solutionIndex * 6) + 1]) / (apolloniusCircles[(solutionIndex * 6) + 0] - mInverse);
720 double intersectionPointY = mInverse * intersectionPointX + b;
722 std::vector<double> circle{intersectionPointX, intersectionPointY, rMax};
723 std::vector<double> IP = calcIntersectionPointCircleLine(circle, mInverse, b, 0);
724 TVector3 apollonius{IP[0], IP[1], rMax};
740 result.push_back(solution);
744 delete[] apolloniusCircles;
751 double x0, y0, r, p, q, intersectionPointX1, intersectionPointY1, intersectionPointX2, intersectionPointY2;
752 if (m == 0 && b == 0) {
757 intersectionPointX1 = Ax;
758 intersectionPointX2 = Ax;
760 intersectionPointY1 = y0 +
sqrt(r * r - (Ax - x0) * (Ax - x0));
761 intersectionPointY2 = y0 -
sqrt(r * r - (Ax - x0) * (Ax - x0));
771 p = (2 * m * (b - y0) - 2 * x0) / (m * m + 1);
772 q = (x0 * x0 + (b - y0) * (b - y0) - r * r) / (m * m + 1);
777 intersectionPointX1 = -p / 2 +
sqrt(p * p / 4 - q);
778 intersectionPointY1 = m * intersectionPointX1 + b;
780 intersectionPointX2 = -p / 2 -
sqrt(p * p / 4 - q);
781 intersectionPointY2 = m * intersectionPointX2 + b;
783 vector<double> intersectionPoints;
784 intersectionPoints.push_back(intersectionPointX1);
785 intersectionPoints.push_back(intersectionPointY1);
786 intersectionPoints.push_back(intersectionPointX2);
787 intersectionPoints.push_back(intersectionPointY2);
788 return intersectionPoints;
848 double MeanSquareDistance = 0.0;
850 std::vector<PndSttHit *> result;
851 if (circle.Z() != 0) {
852 for (
auto sttHit : sttHits) {
859 double squaredDistance = (myHit->GetX() - circle.X()) * (myHit->GetX() - circle.X()) + (myHit->GetY() - circle.Y()) * (myHit->GetY() - circle.Y());
860 double squaredThreshold = (threshold + circle.Z() + sttHit->GetIsochrone()) * (threshold + circle.Z() + sttHit->GetIsochrone());
861 if (squaredDistance >= squaredThreshold) {
864 double d = DistanceCircleSttHit(circle, myHit, squaredDistance);
865 if (sttHit->GetIsochrone() != 0 &&
TMath::Abs(d) < threshold) {
866 result.push_back(myHit);
867 MeanSquareDistance += d * d;
868 }
else if (sttHit->GetIsochrone() == 0 &&
TMath::Abs(d) < threshold + 0.5) {
869 result.push_back(myHit);
870 MeanSquareDistance += d * d;
876 for (
auto sttHit : sttHits) {
881 double squaredDistance = SquaredDistanceLineSttHit(circle, myHit);
882 if (squaredDistance >= (threshold + 0.5) * (threshold + 0.5))
884 double d = DistanceLineSttHit(circle, myHit, squaredDistance);
885 if (sttHit->GetIsochrone() != 0 &&
TMath::Abs(d) < threshold) {
886 result.push_back(myHit);
887 MeanSquareDistance += d * d;
888 }
else if (sttHit->GetIsochrone() == 0 &&
TMath::Abs(d) < threshold + 0.5) {
889 result.push_back(myHit);
890 MeanSquareDistance += d * d;
895 solution.
SortStt(fGeometryMap);
896 solution.
fMeanSquare = MeanSquareDistance / result.size();
904 if (solution.
fTrack.Z() == 0) {
911 double d = DistanceLinePoint(solution.
fTrack, hit);
915 double d = DistanceLinePoint(solution.
fTrack, hit);
919 double d = DistanceLinePoint(solution.
fTrack, hit);
929 double d = DistanceCirclePoint(solution.
fTrack, hit);
933 double d = DistanceCirclePoint(solution.
fTrack, hit);
937 double d = DistanceCirclePoint(solution.
fTrack, hit);
948 TVector2 hitVec{hit->GetX(), hit->GetY()};
949 TVector2 circ{circle.X(), circle.Y()};
952 double distCenters =
sqrt((hitVec.X() - circ.X()) * (hitVec.X() - circ.X()) + (hitVec.Y() - circ.Y()) * (hitVec.Y() - circ.Y()));
953 return (distCenters - circle.Z());
959 TVector2 hit{sttHit->GetX(), sttHit->GetY()};
960 TVector2 circ{circle.X(), circle.Y()};
963 double distCenters =
sqrt((hit.X() - circ.X()) * (hit.X() - circ.X()) + (hit.Y() - circ.Y()) * (hit.Y() - circ.Y()));
964 if (distCenters - circle.Z() > 0) {
965 return (distCenters - circle.Z() - sttHit->
GetIsochrone());
967 return (distCenters - circle.Z() + sttHit->
GetIsochrone());
974 double distCenters =
sqrt(sqaredDistance);
975 if (distCenters - circle.Z() > 0) {
976 return (distCenters - circle.Z() - sttHit->
GetIsochrone());
978 return (distCenters - circle.Z() + sttHit->
GetIsochrone());
997 return sqrt(SquaredDistanceLineSttHit(circle, sttHit));
1003 double m = circle.X();
1004 double b = circle.Y();
1006 double x2 = (sttHit->GetY() + sttHit->GetX() / m - b) / (m + 1 / m);
1007 double y2 = -1 / m * x2 + sttHit->GetY() + sttHit->GetX() /
m;
1009 return ((sttHit->GetX() - x2) * (sttHit->GetX() - x2) + (sttHit->GetY() - y2) * (sttHit->GetY() - y2)) - abs(sttHit->
GetIsochrone());
1015 double m = circle.X();
1016 double b = circle.Y();
1018 double x2 = (hit->GetY() + hit->GetX() / m - b) / (m + 1 / m);
1019 double y2 = -1 / m * x2 + hit->GetY() + hit->GetX() /
m;
1021 double d =
sqrt((hit->GetX() - x2) * (hit->GetX() - x2) + (hit->GetY() - y2) * (hit->GetY() - y2));
1033 solutions.erase(std::remove_if(solutions.begin(), solutions.end(), [&](
TripletSolution &sol) {
return !IsContinuous(sol, fGeometryMap); }), solutions.end());
1047 bool goodSolution =
true;
1049 if (solution.
fHits[TripletSolution::detID::STT].size() == 0) {
1054 solution.
SortStt(fGeometryMap);
1059 for (
auto hit : solution.
fHits[TripletSolution::detID::STT]) {
1061 if (sttHit == previousHit) {
1064 bool good = solutionTest.
CheckTwoHits(previousHit, sttHit);
1070 previousHit = sttHit;
1093 for (
int i = 0;
i < solutions.size();
i++) {
1094 std::vector<int> sectors;
1098 for (
int n = 0; n < solutions[
i].fHits[TripletSolution::detID::STT].size(); n++) {
1101 if (std::find(sectors.begin(), sectors.end(), sectorId) == sectors.end()) {
1102 sectors.push_back(sectorId);
1105 for (
int j = 0; j < sectors.size(); j++) {
1106 vector<int> FirstSectorRow = fStrawMap->
GetStrawRow(sectors[j], 0);
1109 double phiHighTemp =
TMath::ATan2(fStrawMap->
GetTube(FirstSectorRow[FirstSectorRow.size() - 1])->GetPosition().Y(),
1110 fStrawMap->
GetTube(FirstSectorRow[FirstSectorRow.size() - 1])->GetPosition().X());
1112 phiLowTemp = 2 *
TMath::Pi() + phiLowTemp;
1113 if (phiHighTemp < 0)
1114 phiHighTemp = 2 *
TMath::Pi() + phiHighTemp;
1116 if (phiHigh == 0 || phiHigh < phiHighTemp)
1117 phiHigh = phiHighTemp;
1118 if (phiLow == 0 || phiLow > phiLowTemp)
1119 phiLow = phiLowTemp;
1122 for (
auto it = fBranchMap.begin(); it != fBranchMap.end(); it++) {
1123 for (
int j = 0; j < it->second->GetEntriesFast(); j++) {
1124 FairHit *hit = (FairHit *)it->second->At(j);
1129 if (solutions[
i].fTrack.Z() != 0)
1130 d = DistanceCirclePoint(solutions[
i].fTrack, hit);
1131 else if (solutions[
i].fTrack.Z() == 0)
1132 d = DistanceLinePoint(solutions[
i].fTrack, hit);
1134 if (it->first ==
"MVDHitsPixel") {
1139 phi > (phiLow - (30 *
TMath::Pi() / 180.))) {
1140 solutions[
i].AddHit(TripletSolution::detID::MVDpixel, hit);
1143 if (it->first ==
"MVDHitsStrip") {
1148 solutions[
i].AddHit(TripletSolution::detID::MVDstrip, hit);
1151 if (it->first ==
"GEMHit") {
1156 if (it->first ==
"STTHit") {
1160 solutions[
i].AddHit(TripletSolution::detID::STT, hit);
1164 if (it->first ==
"STTCombinedSkewedHits") {
1166 std::pair<Int_t, Int_t> tubeIDs = SkewedSttHit->
GetTubeIDs();
1169 for (
int j = 0; j < fBranchMap[
"STTHit"]->GetEntriesFast(); j++) {
1171 if ((sttHit->
GetTubeID() == tubeIDs.first || sttHit->
GetTubeID() == tubeIDs.second) &&
1172 (std::find(sectors.begin(), sectors.end(), fStrawMap->
GetSector(sttHit->
GetTubeID())) != sectors.end())) {
1173 if (solutions[
i].fHits.count(TripletSolution::detID::STT) == 0) {
1174 solutions[
i].fHits[TripletSolution::detID::STT];
1176 if (std::find(solutions[
i].fHits[TripletSolution::detID::STT].begin(), solutions[
i].fHits[TripletSolution::detID::STT].end(), (FairHit *)sttHit) ==
1177 solutions[
i].fHits[TripletSolution::detID::STT].end()) {
1178 solutions[
i].fHits[TripletSolution::detID::STT].push_back((FairHit *)sttHit);
1186 solutions[
i].fMeanSquare += MeanSquareDistance(solutions[
i]);
1197 std::vector<TripletSolution> result;
1198 LOG(debug) <<
"find best Solution out of " << solutions.size() <<
" possible solutions";
1200 std::vector<TripletSolution> groupedTracks(solutions.size());
1202 int rSize = solutions.size();
1203 std::sort(solutions.begin(), solutions.end(),
1209 LOG(debug) <<
"TrackGroup: " << i++;
1211 LOG(debug) << first;
1214 std::copy_if(solutions.begin(), solutions.end(), groupedTracks.begin(), [&](
TripletSolution &solution) {
1215 bool equalTubes =
true;
1216 std::for_each(solution.fHits[TripletSolution::detID::STT].begin(), solution.fHits[TripletSolution::detID::STT].end(), [&](FairHit *hit) {
1217 if (std::find_if(first.
fHits[TripletSolution::detID::STT].begin(), first.
fHits[TripletSolution::detID::STT].end(), [&](FairHit *firstHit) {
1219 }) == first.
fHits[TripletSolution::detID::STT].end()) {
1223 if (equalTubes ==
true) {
1234 LOG(debug) <<
"GroupedTracks: ";
1235 std::for_each(groupedTracks.begin(), groupedTracks.end(), [](
TripletSolution &sol) { LOG(debug) << sol; });
1237 solutions.resize(nResults);
1239 solutions.erase(std::remove_if(solutions.begin(), solutions.end(),
1241 bool equalTubes =
true;
1242 std::for_each(solution.fHits[TripletSolution::detID::STT].begin(), solution.fHits[TripletSolution::detID::STT].end(), [&](FairHit *hit) {
1243 if (std::find_if(first.
fHits[TripletSolution::detID::STT].begin(), first.
fHits[TripletSolution::detID::STT].end(), [&](FairHit *firstHit) {
1245 }) == first.
fHits[TripletSolution::detID::STT].end()) {
1252 rSize = solutions.size();
1256 result.push_back(groupedTracks[0]);
1259 std::sort(groupedTracks.begin(), groupedTracks.end(),
1262 int maxNHits = groupedTracks[0].fHits[TripletSolution::detID::STT].size();
1264 double lowestMeanSquare = 10000.;
1265 if (groupedTracks[0].fHits[TripletSolution::detID::STT].size() > result[0].fHits[TripletSolution::detID::STT].size()) {
1266 for (
auto track : groupedTracks) {
1267 if (track.fHits[TripletSolution::detID::STT].size() < maxNHits)
1269 if (track.fMeanSquare < lowestMeanSquare) {
1270 lowestMeanSquare = track.fMeanSquare;
1274 result.push_back(best);
1276 LOG(debug) <<
"GroupedTracks solutions: ";
1277 std::for_each(result.begin(), result.end(), [](
TripletSolution &sol) { LOG(debug) << sol; });
1293 LOG(debug) <<
"Combine tracks with identical hits. Expected tracks: " << nExpectedTracks <<
", Found Tracks: " << solutions.size();
1298 std::vector<TripletSolution> result;
1299 if (nExpectedTracks < 1) {
1300 LOG(debug) <<
"-E- no Track expected: " << nExpectedTracks;
1303 int diff = solutions.size() - nExpectedTracks;
1315 std::vector<std::vector<int>> combinations = GetKOutOfN(nExpectedTracks, solutions.size());
1326 result = CheckSolutions(solutions, combinations);
1338 std::vector<TripletSolution>
CheckSolutions(std::vector<TripletSolution> &solutions, std::vector<std::vector<int>> combinations)
1340 std::vector<TripletSolution> result;
1343 std::vector<std::pair<std::vector<int>,
int>> uniqueTubesPerCombination;
1344 std::for_each(combinations.begin(), combinations.end(),
1345 [&](std::vector<int> combi) { uniqueTubesPerCombination.push_back(make_pair(combi, GetUniqueTubeIDs(solutions, combi).size())); });
1348 std::sort(uniqueTubesPerCombination.begin(), uniqueTubesPerCombination.end(),
1349 [](std::pair<std::vector<int>,
int> &first, std::pair<std::vector<int>,
int> &second) {
return first.second > second.second; });
1351 LOG(debug) <<
"Combinations TubeCounts: " << uniqueTubesPerCombination.size();
1356 int highestCount = uniqueTubesPerCombination.front().second;
1358 std::vector<TripletSolution> tmpSolutions;
1359 std::vector<int> solutionsUsed;
1360 for (
auto combi : uniqueTubesPerCombination) {
1361 if (highestCount - combi.second < 1) {
1362 for (
auto sol : combi.first) {
1363 if (std::count(solutionsUsed.begin(), solutionsUsed.end(), sol) == 0) {
1364 tmpSolutions.push_back(solutions[sol]);
1365 solutionsUsed.push_back(sol);
1372 result = tmpSolutions;
1383 std::vector<int>
GetUniqueTubeIDs(std::vector<TripletSolution> &solutions, std::vector<int> combinations)
1385 std::vector<int> result;
1386 std::for_each(combinations.begin(), combinations.end(), [&](
int sol) {
1388 std::for_each(sttHits.begin(), sttHits.end(), [&](FairHit *hit) {
1389 if (std::count(result.begin(), result.end(), ((
PndSttHit *)hit)->GetTubeID()) == 0)
1390 result.push_back(((
PndSttHit *)hit)->GetTubeID());
1405 std::vector<std::vector<int>> result;
1406 std::string bitmask(k, 1);
1407 bitmask.resize(n, 0);
1411 std::vector<int> tmp;
1412 for (
int i = 0;
i < n; ++
i)
1417 result.push_back(tmp);
1418 }
while (std::prev_permutation(bitmask.begin(), bitmask.end()));
1420 LOG(debug) <<
"Combinations: " << result.size();
1427 std::vector<TripletSolution> result;
1430 if (solutions.size() == 0)
1432 for (
auto solution : solutions) {
1433 if (std::none_of(result.begin(), result.end(), [&](
TripletSolution &res) {
return ContainsTriplet(solution.fTriplet, res); })) {
1434 result.push_back(solution);
1444 auto found = std::find(solution.
fHits[TripletSolution::detID::STT].begin(), solution.
fHits[TripletSolution::detID::STT].end(), hit);
1445 if (found == solution.
fHits[TripletSolution::detID::STT].end()) {
1461 std::vector<PndSttHit *>
TubeReduction(std::vector<std::pair<int, int>> &Rows, std::map<
int, std::vector<std::vector<PndSttHit *>>> &tubeStructure,
1462 std::map<FairLink, int> &fMapHitstoCATracklet,
int position)
1464 std::vector<PndSttHit *> result;
1465 std::map<int, std::vector<PndSttHit *>> FoundCAs;
1468 for (
auto row : Rows) {
1469 for (
auto hitGroup : tubeStructure[row.first]) {
1470 if (hitGroup.size() > 5)
1472 for (
auto sttHit : hitGroup) {
1473 auto it = fMapHitstoCATracklet.find(sttHit->GetEntryNr());
1474 if (it == fMapHitstoCATracklet.end()) {
1476 result.push_back(sttHit);
1478 if (FoundCAs.find(fMapHitstoCATracklet[sttHit->GetEntryNr()]) == FoundCAs.end()) {
1481 std::vector<PndSttHit *> temp;
1482 temp.push_back(sttHit);
1483 FoundCAs[fMapHitstoCATracklet[sttHit->GetEntryNr()]] = {temp};
1485 FoundCAs[fMapHitstoCATracklet[sttHit->GetEntryNr()]].push_back(sttHit);
1491 std::map<int, std::vector<PndSttHit *>>::iterator FoundCAsIter;
1493 for (FoundCAsIter = FoundCAs.begin(); FoundCAsIter != FoundCAs.end(); FoundCAsIter++) {
1496 std::sort(FoundCAsIter->second.begin(), FoundCAsIter->second.end());
1497 if (position == 0) {
1498 CASttHit = FoundCAsIter->second[0];
1500 }
else if (position == 1) {
1501 CASttHit = FoundCAsIter->second[FoundCAsIter->second.size() / 2];
1503 }
else if (position == 2) {
1504 CASttHit = FoundCAsIter->second[FoundCAsIter->second.size() - 1];
1507 result.push_back(CASttHit);
1514 std::map<FairLink, int> fMapHitstoCATracklet;
1515 fMapHitstoCATracklet.clear();
1523 for (
int j = 0; j < trackCand_temp.
GetNHits(); j++) {
1527 return fMapHitstoCATracklet;
std::map< int, PndSttHit * > fMapCAToMidTube
std::array< PndSttHit *, 3 > fTripletHits
friend std::ostream & operator<<(std::ostream &output, const TripletSolution &t)
double SquaredDistanceLineSttHit(TVector3 &circle, PndSttHit *sttHit)
std::pair< Int_t, Int_t > GetTubeIDs() const
double fMVDArcLengthCutMid
FairHit * GetFirstHit(PndSttGeometryMap *fGeometryMap)
friend F32vec4 sqrt(const F32vec4 &a)
void AddHits(detID detector, std::vector< FairHit *> data)
double fDistanceThresholdMVDMid1
PndTrackCand GetFirstTrackCand(int i)
friend std::ostream & operator<<(std::ostream &output, const Triplet &t)
double fDistanceThresholdSTTFar
PndTrackCandHit GetSortedHit(UInt_t i)
std::vector< Triplet > ReduceCombinatorics(TripletValues &triplets, std::map< FairLink, int > &fMapHitstoCATracklet, TClonesArray *sttHits, PndSttCA *fCATrackFinder, PndSttGeometryMap *fGeometryMap, double &fMinDistance, bool &fWithCombiReduction)
Find triplet combinations with higher probability to be a proper one.
double fDistanceThresholdSTTCombinedSkewed
std::map< int, std::vector< std::vector< PndSttHit * > > > GetTubeStructure(std::vector< PndSttHit *> hits, PndSttGeometryMap *fGeometryMap, int &fAllHitsCounter, bool &fIsStrongCurling)
Creates a map that connects each STT row with a set of groups. All STT hits in one group are directly...
bool IsSkewedStraw(int strawindex) const
double MeanSquareDistance(TripletSolution &solution)
double fDistanceThresholdGEM
int GetRow(int strawindex) const
double fMVDArcLengthCutNarrow
static void ApolloniusCudaCalcCPU(int num, double hit0[], double hit1[], double hit2[], double apolloniusCircles[])
Calculation of Apollonius circles on CPU. (This is the same as implemented in cuda).
std::vector< TripletSolution > FindBestSolutions(std::vector< TripletSolution > &solutions)
Select best solution(s) out of the 8 generated by triplet.
TripletValues & operator+=(const TripletValues &right)
TripletSolution FindHitsCloseToCircle(std::vector< PndSttHit *> &sttHits, TVector3 &circle, double &fDistanceThresholdSTTFar, PndSttGeometryMap *fGeometryMap)
Finds all hits that are close to a specific circle.
void AddHit(detID detector, FairHit *data)
void SortHits(TVector2 &firstHit, detID detector)
double DistanceCircleSttHit(TVector3 &circle, PndSttHit *sttHit, double &sqaredDistance)
double DistanceCircleSttHit(TVector3 &circle, PndSttHit *sttHit)
std::map< int, PndSttHit * > fMapCAToOuterTube
friend std::ostream & operator<<(std::ostream &output, const TripletValues &t)
virtual bool CheckFirstHit(FairLink *hit)
std::vector< TripletSolution > CombineIdenticalSolutions(std::vector< TripletSolution > &solutions)
std::map< FairLink, int > GetHitsToCAMap(PndSttCA *fCATrackFinder)
int GetSector(int strawindex) const
void CheckContinuitySolutions(std::vector< TripletSolution > &solutions, PndSttGeometryMap *fGeometryMap)
Checks if a track candidate is continuous in the STT.
double DistanceLineSttHit(TVector3 &circle, PndSttHit *sttHit)
std::map< PndSttHit *, int > fMapInnerTubeToCA
double fDistanceThresholdMVDFar
std::vector< std::vector< int > > GetKOutOfN(int k, int n)
Determines all possible combinations of tracks.
std::vector< TripletSolution > CheckSolutions(std::vector< TripletSolution > &solutions, std::vector< std::vector< int >> combinations)
Check Combined Track Solutions if they are a possible solution.
double fDistanceThresholdSTTNarrow
const vector< int > & GetStrawRow(int sector, int row) const
double DistanceLinePoint(TVector3 &circle, FairHit *hit)
bool ContainsTriplet(Triplet &triplet, TripletSolution &solution)
TVector2 HitOnTrack(FairHit *hit)
bool IsTripletUsed(std::vector< TripletSolution > &solutions, Triplet &triplet)
Checks is the triplet is already found in a good solution.
static T ATan2(const T &y, const T &x)
std::vector< double > calcIntersectionPointCircleLine(std::vector< double > circle, double m, double b, double Ax)
double fDistanceThresholdMVDMid2
std::vector< PndSttHit * > fFirstRow
double fDistanceThresholdSTTSkewed
PndSttTube * GetTube(int strawindex) const
bool IsSkewedStraw(int strawindex) const
std::vector< TripletSolution > GenerateTripletTracks(Triplet triplet, std::vector< PndSttHit *> &sttHits, PndSttGeometryMap *fGeometryMap)
Generate tracks for one triplet.
std::vector< int > GetUniqueTubeIDs(std::vector< TripletSolution > &solutions, std::vector< int > combinations)
returns a vector of all tubes of all tracks in one combination
std::map< int, std::vector< PndSttHit * > > GetAllTubesByRow(std::vector< PndSttHit *> hits, PndSttGeometryMap *fGeometryMap, int &fAllHitsCounter)
Sorts all STT hits by row and returns a map that connects each row with the hits in that row...
void AddOtherDetectors(vector< TripletSolution > &solutions, PndSttStrawMap *fStrawMap, std::map< TString, TClonesArray *> &fBranchMap)
Add MVD and GEM hits to solutions.
double fMVDArcLengthCutFar
ReductionMaps CreateMaps(TripletValues &triplets, std::map< FairLink, int > &fMapHitstoCATracklet)
Created maps that connect the hits with a corresponding CA tracklet.
virtual bool CheckTwoHits(FairLink *first, FairLink *second)
double fDistanceThresholdMVDNarrow
void SortAllHits(PndSttGeometryMap *fGeometryMap)
Double_t GetIsochrone() const
TripletSolution(TVector3 track)
std::map< detID, std::vector< FairHit * > > fHits
std::vector< PndSttHit * > fMidRow
double DistanceCirclePoint(TVector3 &circle, FairHit *hit)
void AddHits(std::vector< PndSttHit *> sttHits)
std::vector< PndSttHit * > fLastRow
std::vector< PndSttHit * > TubeReduction(std::vector< std::pair< int, int >> &Rows, std::map< int, std::vector< std::vector< PndSttHit *>>> &tubeStructure, std::map< FairLink, int > &fMapHitstoCATracklet, int position)
Reduces the number of tubes chosen for combination–> if several tubes in one region (inner...
std::map< PndSttHit *, int > fMapMidTubeToCA
std::vector< TripletSolution > CheckCombinedSolutions(std::vector< TripletSolution > &solutions, int nExpectedTracks)
Combines and Checks all Solutions to generate only the true particle tracks.
double DistanceLineSttHit(TVector3 &circle, PndSttHit *sttHit, double &squaredDistance)
std::vector< FairHit * > fAllHits
std::vector< std::string > detID_Names
void SortStt(PndSttGeometryMap *fGeometryMap)
bool IsContinuous(TripletSolution &solution, PndSttGeometryMap *fGeometryMap)
Checks if te found STT hits are continuous.