74 std::vector<trkf::BezierTrack> ReturnVector;
76 size_t UEntries = SortedHits[0].size();
77 size_t VEntries = SortedHits[1].size();
78 size_t WEntries = SortedHits[2].size();
82 std::vector< std::vector< std::vector<int> > > OrgHitsU(UEntries);
83 std::vector< std::vector< std::vector<int> > > OrgHitsV(VEntries);
84 std::vector< std::vector< std::vector<int> > > OrgHitsW(WEntries);
90 std::vector<double> MinUTime(UEntries,10000);
91 std::vector<double> MaxUTime(UEntries,0);
92 std::vector<double> MinVTime(VEntries,10000);
93 std::vector<double> MaxVTime(VEntries,0);
94 std::vector<double> MinWTime(WEntries,10000);
95 std::vector<double> MaxWTime(WEntries,0);
97 std::vector<int> MinUWire(UEntries,10000);
98 std::vector<int> MaxUWire(UEntries,0);
99 std::vector<int> MinVWire(VEntries,10000);
100 std::vector<int> MaxVWire(VEntries,0);
101 std::vector<int> MinWWire(WEntries,10000);
102 std::vector<int> MaxWWire(WEntries,0);
105 for(
size_t nU=0; nU!=UEntries; ++nU)
107 OrgHitsU[nU].resize(NChannels);
108 for(
size_t iH=0; iH!=SortedHits[0][nU].size(); ++iH)
110 OrgHitsU[nU][SortedHits[0][nU][iH]->Channel()].push_back(iH);
111 double Time = SortedHits[0][nU][iH]->PeakTime();
112 if(Time<MinUTime[nU]) MinUTime[nU]=Time;
113 if(Time>MaxUTime[nU]) MaxUTime[nU]=Time;
114 int Wire = SortedHits[0][nU][iH]->WireID().Wire;
115 if(Wire<MinUWire[nU]) MinUWire[nU]=Wire;
116 if(Wire>MaxUWire[nU]) MaxUWire[nU]=Wire;
123 for(
size_t nV=0; nV!=VEntries; ++nV)
125 OrgHitsV[nV].resize(NChannels);
126 for(
size_t iH=0; iH!=SortedHits[1][nV].size(); ++iH)
128 OrgHitsV[nV][SortedHits[1][nV][iH]->Channel()].push_back(iH);
129 double Time = SortedHits[1][nV][iH]->PeakTime();
130 if(Time<MinVTime[nV]) MinVTime[nV]=Time;
131 if(Time>MaxVTime[nV]) MaxVTime[nV]=Time;
132 int Wire = SortedHits[1][nV][iH]->WireID().Wire;
133 if(Wire<MinVWire[nV]) MinVWire[nV]=Wire;
134 if(Wire>MaxVWire[nV]) MaxVWire[nV]=Wire;
140 for(
size_t nW=0; nW!=WEntries; ++nW)
142 OrgHitsW[nW].resize(NChannels);
143 for(
size_t iH=0; iH!=SortedHits[2][nW].size(); ++iH)
145 OrgHitsW[nW][SortedHits[2][nW][iH]->Channel()].push_back(iH);
146 double Time = SortedHits[2][nW][iH]->PeakTime();
147 if(Time<MinWTime[nW]) MinWTime[nW]=Time;
148 if(Time>MaxWTime[nW]) MaxWTime[nW]=Time;
149 int Wire = SortedHits[2][nW][iH]->WireID().Wire;
150 if(Wire<MinWWire[nW]) MinWWire[nW]=Wire;
151 if(Wire>MaxWWire[nW]) MaxWWire[nW]=Wire;
157 for(
size_t nU =0; nU != UEntries; ++nU)
158 for(
size_t nV =0; nV != VEntries; ++nV)
159 for(
size_t nW =0; nW != WEntries; ++nW)
166 if(MaxUTime[nU] < MinWTime[nW] )
continue;
167 if(MaxUTime[nU] < MinVTime[nV] )
continue;
168 if(MaxVTime[nV] < MinUTime[nU] )
continue;
169 if(MaxVTime[nV] < MinWTime[nW] )
continue;
170 if(MaxWTime[nW] < MinUTime[nU] )
continue;
171 if(MaxWTime[nW] < MinVTime[nV] )
continue;
175 double MinTime =
std::max(
std::max(MinUTime[nU],MinVTime[nV]),MinWTime[nW])-SpacePointRes;
176 double MaxTime =
std::min(
std::min(MaxUTime[nU],MaxVTime[nV]),MaxWTime[nW])+SpacePointRes;
182 if(MaxUVOnW < MinWWire[nW])
continue;
185 if(MinUVOnW > MaxWWire[nW])
continue;
192 double EffMaxTime = MaxTime + fPlaneTimeOffsets[0];
194 for(
size_t i=0; i!=SortedHits[0][nU].size(); ++i)
195 if((SortedHits[0][nU][i]->PeakTimePlusRMS(+1.) > EffMinTime)
196 &&(SortedHits[0][nU][i]->PeakTimePlusRMS(-1.)<EffMaxTime))
197 HitsFlat.
push_back(SortedHits[0][nU][i]);
199 EffMinTime = MinTime + fPlaneTimeOffsets[1];
200 EffMaxTime = MaxTime + fPlaneTimeOffsets[1];
202 for(
size_t i=0; i!=SortedHits[1][nV].size(); ++i)
203 if((SortedHits[1][nV][i]->PeakTimePlusRMS(+1.)>EffMinTime)
204 &&(SortedHits[1][nV][i]->PeakTimePlusRMS(-1.)<EffMaxTime))
205 HitsFlat.
push_back(SortedHits[1][nV][i]);
207 EffMinTime = MinTime + fPlaneTimeOffsets[2];
208 EffMaxTime = MaxTime + fPlaneTimeOffsets[2];
210 for(
size_t i=0; i!=SortedHits[2][nW].size(); ++i)
211 if((SortedHits[2][nW][i]->PeakTimePlusRMS(+1.)>EffMinTime)
212 &&(SortedHits[2][nW][i]->PeakTimePlusRMS(-1.)<EffMaxTime))
213 HitsFlat.
push_back(SortedHits[2][nW][i]);
215 std::vector<art::PtrVector<recob::Hit> > HitsPerSeed;
217 std::vector<recob::Seed> SeedsThisCombo =
221 if(SeedsThisCombo.size()>0)
225 std::vector<art::PtrVector<recob::Hit>* > HitStruct(3);
226 HitStruct[0] = & SortedHits[0].at(nU);
227 HitStruct[1] = & SortedHits[1].at(nV);
228 HitStruct[2] = & SortedHits[2].at(nW);
230 std::vector<std::vector< std::vector<int> >* > OrgHits(3);
231 OrgHits[0] = & OrgHitsU[nU];
232 OrgHits[1] = & OrgHitsV[nV];
233 OrgHits[2] = & OrgHitsW[nW];
237 std::vector<std::vector<std::vector<int > > > HitsPerTrack;
239 std::vector<std::vector<recob::Seed> > SeedsForTracks =
OrganizeSeedsIntoTracks(SeedsThisCombo, HitStruct, HitsPerSeed, OrgHits, HitsPerTrack);
240 for(
size_t iTrack=0; iTrack!=SeedsForTracks.size(); ++iTrack)
242 std::vector<std::pair<int, int> > ClustersThisTrack;
243 ClustersThisTrack.push_back(std::pair<int,int>(0,nU));
244 ClustersThisTrack.push_back(std::pair<int,int>(1,nV));
245 ClustersThisTrack.push_back(std::pair<int,int>(2,nW));
247 ClustersUsed.push_back(ClustersThisTrack);
253 for(
size_t iH=0; iH!=HitsPerTrack.at(iTrack)[0].size(); ++iH)
254 HitsForThisTrack.
push_back(SortedHits[
geo::kU][nU][HitsPerTrack.at(iTrack)[0].at(iH)]);
256 for(
size_t iH=0; iH!=HitsPerTrack.at(iTrack)[1].size(); ++iH)
257 HitsForThisTrack.
push_back(SortedHits[
geo::kV][nV][HitsPerTrack.at(iTrack)[1].at(iH)]);
259 for(
size_t iH=0; iH!=HitsPerTrack.at(iTrack)[2].size(); ++iH)
260 HitsForThisTrack.
push_back(SortedHits[
geo::kW][nW][HitsPerTrack.at(iTrack)[2].at(iH)]);
262 HitAssocs.push_back(HitsForThisTrack);
279 std::map<int, bool> ToErase;
281 std::vector<double> Lengths;
282 std::vector<TVector3> End1Points, End2Points;
285 for(
size_t i=0; i!=BTracks.size(); ++i)
287 End1Points.push_back(BTracks.at(i).GetTrackPointV(0));
288 End2Points.push_back(BTracks.at(i).GetTrackPointV(1));
289 Lengths.push_back(BTracks.at(i).GetLength());
292 for(
size_t t1=0;
t1!=BTracks.size(); ++
t1)
293 for(
size_t t2=0;
t2!=BTracks.size(); ++
t2)
297 if(Lengths.at(
t1)>Lengths.at(
t2))
300 BTracks.at(
t1).GetClosestApproach(End1Points.at(
t2),s1,d1);
301 BTracks.at(
t1).GetClosestApproach(End2Points.at(
t2),s2,d2);
302 if((s1>0.01)&&(s1<0.99)&&(s2>0.01)&&(s2<0.99)&&
312 BTracks.at(
t2).GetClosestApproach(End1Points.at(
t1),s1,d1);
313 BTracks.at(
t2).GetClosestApproach(End2Points.at(
t1),s2,d2);
314 if((s1>0.01)&&(s1<0.99)&&(s2>0.01)&&(s2<0.99)&&
325 for(
int i=BTracks.size()-1; i >= 0; --i)
329 BTracks.erase(BTracks.begin()+i);
330 HitVecs.erase(HitVecs.begin()+i);
331 ClustersUsed.erase(ClustersUsed.begin()+i);
343 std::vector<double> Lengths;
344 std::vector<TVector3> End1Directions, End1Points, End2Directions, End2Points;
345 for(
size_t i=0; i!=BTracks.size(); ++i)
347 Lengths.push_back(BTracks.at(i).GetLength());
348 End1Points.push_back(BTracks.at(i).GetTrackPointV(0));
349 End2Points.push_back(BTracks.at(i).GetTrackPointV(1));
350 End1Directions.push_back(BTracks.at(i).GetTrackDirectionV(0).Unit());
351 End2Directions.push_back(BTracks.at(i).GetTrackDirectionV(1).Unit());
358 for(
size_t t1=0;
t1!=BTracks.size(); ++
t1)
360 for(
size_t t2=0;
t2!=BTracks.size(); ++
t2)
366 BTracks.at(
t1).GetClosestApproach(End1Points.at(
t2),s12,d12);
367 BTracks.at(
t2).GetClosestApproach(End2Points.at(
t1),s21,d21);
369 if((s12>0.0001)&&(s12<0.999)
370 &&(s21>0.0001)&&(s21<0.999)
378 BTracks.erase(BTracks.begin()+
t2);
382 ClustersUsed.at(
t1).insert(ClustersUsed.at(
t1).begin(),
383 ClustersUsed.at(
t2).begin(),
384 ClustersUsed.at(
t2).end());
386 HitVecs.erase(HitVecs.begin()+
t2);
387 ClustersUsed.erase(ClustersUsed.begin()+
t2);
392 if(LoopStatus==3)
break;
394 if(LoopStatus==3)
break;
404 std::vector<double> Lengths;
405 std::vector<int> SortedOrder;
406 std::vector<bool> Counted(BTracks.size());
408 for(
size_t i=0; i!=BTracks.size(); ++i)
410 Lengths.push_back(BTracks.at(i).GetLength());
411 if(BTracks.at(i).GetTrackDirectionV(0.0).Dot(
fZDir)<0.0) BTracks.at(i)=BTracks.at(i).Reverse();
413 while(SortedOrder.size()<BTracks.size())
416 for(
size_t i=0; i!=BTracks.size(); ++i)
420 if(Longest==-1) Longest=i;
422 if(Lengths.at(i)>Lengths.at(Longest)) Longest=i;
425 Counted[Longest]=
true;
426 SortedOrder.push_back(Longest);
429 std::vector<trkf::BezierTrack> BTracksNew;
430 std::vector<art::PtrVector<recob::Hit> > HitVecsNew;
431 std::vector<std::vector<std::pair<int, int> > > ClustersUsedNew;
432 for(
size_t i=0; i!=SortedOrder.size(); ++i)
434 BTracksNew.push_back(BTracks.at(SortedOrder.at(i)));
435 HitVecsNew.push_back(HitVecs.at(SortedOrder.at(i)));
436 ClustersUsedNew.push_back(ClustersUsed.at(SortedOrder.at(i)));
441 ClustersUsed=ClustersUsedNew;
460 for(
size_t t1=0;
t1!=BTracks.size(); ++
t1)
462 for(
size_t t2=0;
t2!=BTracks.size(); ++
t2)
466 TVector3 End1Dir_i = BTracks.at(
t1).GetTrackDirectionV(1.0).Unit();
467 TVector3 End0Dir_j = BTracks.at(
t2).GetTrackDirectionV(0.0).Unit();
469 TVector3 End0Point_i = BTracks.at(
t1).GetTrackPointV(0.0);
470 TVector3 End0Point_j = BTracks.at(
t2).GetTrackPointV(0.0);
471 TVector3 End1Point_i = BTracks.at(
t1).GetTrackPointV(1.0);
472 TVector3 End1Point_j = BTracks.at(
t2).GetTrackPointV(1.0);
476 double JoinAngle = End1Dir_i.Angle(End0Dir_j);
477 double JoinSign = (End0Point_j-End1Point_i).Dot(End1Dir_i);
478 double Colinearity = ((End0Point_j-End1Point_i) - End1Dir_i*((End0Point_j-End1Point_i).Dot(End1Dir_i))).Mag();
483 double EndSep10 = (End1Point_i-End0Point_j).Mag();
484 double EndSep01 = (End0Point_i-End1Point_j).Mag();
485 double EndSep11 = (End1Point_i-End1Point_j).Mag();
486 double EndSep00 = (End0Point_i-End0Point_j).Mag();
490 &&(EndSep10 < EndSep11)
491 &&(EndSep10 < EndSep00)
492 &&(EndSep10 < EndSep01) )
496 BTracks.erase(BTracks.begin()+
t2);
500 ClustersUsed.at(
t1).insert(ClustersUsed.at(
t1).begin(),
501 ClustersUsed.at(
t2).begin(),
502 ClustersUsed.at(
t2).end());
504 HitVecs.erase(HitVecs.begin()+
t2);
505 ClustersUsed.erase(ClustersUsed.begin()+
t2);
509 if(LoopStatus==3)
break;
511 if(LoopStatus==3)
break;
525 SeedCol1.insert(SeedCol1.end(),SeedCol2.begin(),SeedCol2.end());
535 for(
size_t i=0; i!=ToAdd.
size(); ++i)
547 mf::LogVerbatim(
"BezierTrackerAlgorithm")<<
"Organizing seed collection into track collections ";
549 std::vector<std::vector<uint32_t> > MaxSeedChanPerView(3);
550 std::vector<std::vector<uint32_t> > MinSeedChanPerView(3);
558 std::vector<std::vector<int> > HitStatus(3);
559 for(
size_t n=0;
n!=3; ++
n) HitStatus.at(
n).resize(AllHits[
n]->size());
566 std::vector<std::vector<std::vector<int> > > SeedToHitMap(3);
569 for(
size_t iSeed=0; iSeed!=AllSeeds.size(); ++iSeed)
573 bool CompleteSet =
false;
574 std::vector<bool> AtLeastOneHitThisView(3,
false);
575 for(
size_t iHit=0; iHit!=WhichHitsPerSeed.at(iSeed).size(); ++iHit)
577 if(!AtLeastOneHitThisView[WhichHitsPerSeed.at(iSeed).at(iHit)->View()])
579 AtLeastOneHitThisView[WhichHitsPerSeed.at(iSeed).at(iHit)->View()] =
true;
580 if(AtLeastOneHitThisView[0]&&AtLeastOneHitThisView[1]&&AtLeastOneHitThisView[2])
592 AllSeeds.erase(AllSeeds.begin() + iSeed);
593 WhichHitsPerSeed.erase(WhichHitsPerSeed.begin() + iSeed);
602 for(
size_t n=0;
n!=3; ++
n)
604 SeedToHitMap[
n].push_back(std::vector<int>());
605 MinSeedChanPerView[
n].push_back(10000);
606 MaxSeedChanPerView[
n].push_back(0);
608 for(
size_t iHit=0; iHit!=WhichHitsPerSeed.at(iSeed).size(); ++iHit)
610 uint32_t Channel = WhichHitsPerSeed.at(iSeed).at(iHit)->Channel();
611 geo::View_t View = WhichHitsPerSeed.at(iSeed).at(iHit)->View();
615 else if(View==
geo::kV) ViewID=1;
616 else if(View==
geo::kW) ViewID=2;
620 for(
size_t iH=0; iH!=OrgHits[ViewID]->at(Channel).size();++iH)
622 double PeakTime1 = AllHits[ViewID]->at(OrgHits[ViewID]->at(Channel).at(iH))->PeakTime();
623 double PeakTime2 = WhichHitsPerSeed.at(iSeed).at(iHit)->PeakTime();
625 if( fabs(PeakTime1-PeakTime2)<eta)
627 SeedToHitMap[ViewID][iSeed].push_back(OrgHits[ViewID]->at(Channel).at(iH));
631 if(Channel>MaxSeedChanPerView[ViewID][iSeed]) MaxSeedChanPerView[ViewID][iSeed] = Channel;
632 if(Channel<MinSeedChanPerView[ViewID][iSeed]) MinSeedChanPerView[ViewID][iSeed] = Channel;
642 std::vector<std::vector<recob::Seed > > OrganizedByTrack;
646 std::vector<TVector3> VSeedDirs;
647 std::vector<TVector3> VSeedPoss;
648 std::vector<std::vector<int> > SeedSDirs;
649 std::vector<std::vector<uint32_t> > SeedHighSChans;
650 std::vector<std::vector<uint32_t> > SeedLowSChans;
654 for(
size_t i=0; i!=AllSeeds.size(); ++i)
656 double SeedDir[3], SeedPos[3], Err[3];
658 AllSeeds.at(i).GetDirection(SeedDir,Err);
659 AllSeeds.at(i).GetPoint(SeedPos,Err);
660 TVector3 VSeedDir = TVector3(SeedDir[0],SeedDir[1],SeedDir[2]);
661 VSeedDirs.push_back(VSeedDir);
662 TVector3 VSeedPos = TVector3(SeedPos[0],SeedPos[1],SeedPos[2]);
663 VSeedPoss.push_back(VSeedPos);
668 if(VSeedDir.Dot(
fZDir)<0)
669 AverageDir -= VSeedDir;
671 AverageDir += VSeedDir;
674 std::vector<double> TimeDir, WireDir;
678 SeedSDirs.push_back(std::vector<int>(3));
679 SeedHighSChans.push_back(std::vector<uint32_t>(3));
680 SeedLowSChans.push_back(std::vector<uint32_t>(3));
683 for(
size_t n=0;
n!=3; ++
n)
688 SeedHighSChans[i][
n] = MaxSeedChanPerView[
n][i];
689 SeedLowSChans[i][
n] = MinSeedChanPerView[
n][i];
694 SeedHighSChans[i][
n] = MinSeedChanPerView[
n][i];
695 SeedLowSChans[i][
n] = MaxSeedChanPerView[
n][i];
700 AverageDir *= (1.0/AverageDir.Mag());
702 std::vector<double> AngleToAve;
703 std::vector<double> ProjAlongAve;
705 for(
size_t i=0; i!=AllSeeds.size(); ++i)
707 ProjAlongAve.push_back(VSeedPoss.at(i).Dot(AverageDir));
708 AngleToAve.push_back(VSeedDirs.at(i).Dot(AverageDir)/VSeedDirs.at(i).Mag());
715 std::vector<size_t> TrackParts;
716 std::vector<size_t> DoesNotFit;
717 std::vector<size_t> AlreadyUsed;
718 std::vector<size_t> ThrownByHits;
719 std::map<int, bool> SeedNotAvailable;
722 while((AlreadyUsed.size()+ThrownByHits.size())<AllSeeds.size())
729 while((ThrownByHits.size()+TrackParts.size()+DoesNotFit.size()+AlreadyUsed.size())<AllSeeds.size())
734 for(
size_t i=0; i!=AllSeeds.size(); ++i)
736 if(!SeedNotAvailable[i])
738 if(LowestLeft < 0) LowestLeft = i;
739 if(ProjAlongAve.at(i)<ProjAlongAve.at(LowestLeft))
744 std::vector<std::vector<int> > InterpHits(3);
746 if(TrackParts.size()==0)
750 TrackParts.push_back(LowestLeft);
751 SeedNotAvailable[LowestLeft]=
true;
754 for(
size_t View=0; View!=3; ++View)
755 for(
size_t iH=0; iH!=SeedToHitMap[View][LowestLeft].size();++iH)
756 HitStatus[View][SeedToHitMap[View][LowestLeft][iH]] = 2;
759 else if(TrackParts.size()>0)
761 int a = TrackParts.at(TrackParts.size()-1);
764 double Angle = AllSeeds.at(a).GetAngle(AllSeeds.at(b));
765 double ProjDisc = AllSeeds.at(a).GetProjAngleDiscrepancy(AllSeeds.at(b));
766 int PointingSign_ab = AllSeeds.at(a).GetPointingSign(AllSeeds.at(b));
767 int PointingSign_ba = AllSeeds.at(b).GetPointingSign(AllSeeds.at(a));
768 int PointingSign_ac = 0;
770 if(TrackParts.size()>1) PointingSign_ac = AllSeeds.at(a).GetPointingSign(AllSeeds.at(TrackParts.size()-2));
776 bool PointingSignOK = (PointingSign_ac * PointingSign_ab)<0.5;
777 bool ProjDiscOK =
false;
778 if(PointingSign_ab > 0)
787 if(JoinAngleOK && PointingSignOK && ProjDiscOK)
789 std::vector<uint32_t> EndChan_a(3), EndChan_b(3), LowChan(3), HighChan(3);
790 std::vector<std::vector<int> > HitsUnderConsideration(3);
792 for(
size_t n=0;
n!=3; ++
n)
794 if(PointingSign_ab > 0)
795 EndChan_a[
n] = SeedHighSChans[a][
n];
797 EndChan_a[
n] = SeedLowSChans[a][
n];
799 if(PointingSign_ba > 0)
800 EndChan_b[
n] = SeedHighSChans[b][
n];
802 EndChan_b[
n] = SeedLowSChans[b][
n];
804 LowChan[
n] =
std::min(EndChan_a[
n], EndChan_b[n]) ;
805 HighChan[
n] =
std::max(EndChan_a[n], EndChan_b[n]) ;
808 std::vector<std::vector<int> > TheseHits(3);
816 TrackParts.push_back(LowestLeft);
817 SeedNotAvailable[LowestLeft]=
true;
820 for(
size_t View=0; View!=3; ++View)
821 for(
size_t iH=0; iH!=SeedToHitMap[View][LowestLeft].size();++iH)
822 HitStatus[View][SeedToHitMap[View][LowestLeft][iH]] = 2;
824 for(
size_t n=0;
n!=3; ++
n)
825 for(
size_t i=0; i!=InterpHits[
n].size(); ++i)
827 HitStatus[
n][InterpHits[
n][i]] = 1;
831 for(
size_t j=0; j!=AllSeeds.size(); ++j)
833 if(!SeedNotAvailable[j])
835 double OverlapFrac[3];
836 for(
size_t n=0;
n!=3; ++
n)
840 for(
size_t iH=0; iH!=SeedToHitMap[
n][j].size(); ++iH)
843 if(HitStatus[
n][SeedToHitMap[
n][j][iH]]!=0)
846 OverlapFrac[
n] = float(TotalRejected)/float(TotalInSeed);
848 for(
size_t n=0;
n!=3; ++
n)
850 size_t n1=(
n+1)%3;
size_t n2=(
n+2)%3;
851 if( (OverlapFrac[
n]<=OverlapFrac[n1]) &&
852 (OverlapFrac[
n]<=OverlapFrac[n2]) )
856 SeedNotAvailable[j]=
true;
857 ThrownByHits.push_back(j);
871 DoesNotFit.push_back(LowestLeft);
872 SeedNotAvailable[LowestLeft]=
true;
876 if(TrackParts.size()>0)
878 mf::LogVerbatim(
"BezierTrackerAlgorithm")<<
" Prototrack runs through seeds: " ;
879 std::vector<recob::Seed> TheTrackSeeds;
881 TVector3 AveTrackDir =
882 VSeedPoss.at(TrackParts.at(TrackParts.size()-1))
883 - VSeedPoss.at(TrackParts.at(0));
885 for(
size_t i=0; i!=TrackParts.size(); ++i)
887 mf::LogVerbatim(
"BezierTrackerAlgorithm")<<
" " << TrackParts.at(i)<<
", ";
888 if(VSeedDirs.at(TrackParts.at(i)).Dot(AveTrackDir)>0)
889 TheTrackSeeds.push_back(AllSeeds.at(TrackParts.at(i)));
891 TheTrackSeeds.push_back(AllSeeds.at(TrackParts.at(i)).Reverse());
892 AlreadyUsed.push_back(TrackParts.at(i));
894 OrganizedByTrack.push_back(TheTrackSeeds);
896 HitsWithTracks.push_back(
std::vector<std::vector<int> >(3));
897 for(
size_t n=0;
n!=3; ++
n)
898 for(
size_t iH=0; iH!=HitStatus[
n].size(); ++iH)
900 if((HitStatus[
n][iH]==1)||(HitStatus[
n][iH]==2))
903 HitsWithTracks[HitsWithTracks.size()-1][
n].push_back(iH);
910 SeedNotAvailable.clear();
914 for(
size_t j=0; j!=AlreadyUsed.size(); ++j)
916 SeedNotAvailable[AlreadyUsed[j]]=
true;
921 for(
size_t i=0; i!=DoesNotFit.size(); ++i)
923 size_t j=DoesNotFit[i];
924 double OverlapFrac[3];
925 for(
size_t n=0;
n!=3; ++
n)
929 for(
size_t iH=0; iH!=SeedToHitMap[
n][j].size(); ++iH)
932 if(HitStatus[
n][SeedToHitMap[
n][j][iH]]!=0)
935 OverlapFrac[
n] = float(TotalRejected)/float(TotalInSeed);
937 for(
size_t n=0;
n!=3; ++
n)
939 size_t n1=(
n+1)%3;
size_t n2=(
n+2)%3;
940 if( (OverlapFrac[
n]<=OverlapFrac[n1]) &&
941 (OverlapFrac[
n]<=OverlapFrac[n2]) )
945 SeedNotAvailable[j]=
true;
946 ThrownByHits.push_back(j);
954 for(
size_t i=0; i!=ThrownByHits.size(); ++i)
955 SeedNotAvailable[ThrownByHits[i]]=
true;
963 return OrganizedByTrack;
973 int NSteps = 2 * Seed1.
GetDistance(Seed2) / dThresh;
974 if(NSteps<2) NSteps=2;
977 std::vector<TVector3> Pts = bhlp.
GetBezierPoints(Seed2, Seed1, NSteps);
980 for(
size_t n=0;
n!=3; ++
n)
982 if((HighChan[
n]-LowChan[
n])<=2)
continue;
984 size_t EmptyChanLimit = int((1.-
fOccupancyThresh)*(HighChan[n]-LowChan[n]-2));
985 size_t NEmptyChannels=0;
987 for(uint32_t iChan = LowChan[n]+1; iChan < (HighChan[
n]-1); ++iChan)
989 bool GotThisChannel=
false;
991 for(
size_t iH = 0; iH!=OrgHits[
n]->at(iChan).size(); ++iH)
993 if(HitStatus[n][OrgHits[n]->at(iChan).at(iH)]==0)
999 for(
size_t ipt=0; ipt!=Pts.size(); ++ipt)
1001 float d = ((WirePoint1-Pts.at(ipt))-
fWireDir[n]*((WirePoint1-Pts.at(ipt)).Dot(
fWireDir[n]))).Mag();
1004 TheseHits[
n].push_back(OrgHits[n]->at(iChan).at(iH));
1005 GotThisChannel=
true;
1011 if(!GotThisChannel) NEmptyChannels++;
1012 if(NEmptyChannels > EmptyChanLimit)
return false;
1027 WireCoord.resize(3);
1029 TimeCoord.resize(3);
1031 double dir[3], err[3];
1034 TVector3 DirVec(dir[0],dir[1],dir[2]);
1036 for(
size_t n=0;
n!=3; ++
n)
1063 for(
size_t n=0;
n!=3; ++
n)
1067 fXDir = TVector3(1,0,0);
1068 fYDir = TVector3(0,1,0);
1069 fZDir = TVector3(0,0,1);
1075 double xyzStart1[3], xyzStart2[3];
1076 double xyzEnd1[3], xyzEnd2[3];
1079 for(
size_t n=0;
n!=3; ++
n)
1083 fWireDir[
n] = TVector3(xyzEnd1[0] - xyzStart1[0],
1084 xyzEnd1[1] - xyzStart1[1],
1085 xyzEnd1[2] - xyzStart1[2]).Unit();
1087 if(
fPitchDir[
n].Dot(TVector3(xyzEnd2[0] - xyzEnd1[0],
1088 xyzEnd2[1] - xyzEnd1[1],
1106 std::vector<TVector3> TrackEnd1s;
1107 std::vector<TVector3> TrackEnd2s;
1108 std::vector<TVector3> TrackDir1s;
1109 std::vector<TVector3> TrackDir2s;
1112 for(
size_t i=0; i!=BTracks.size(); ++i)
1114 TrackEnd1s.push_back( BTracks.at(i).GetTrackPointV(0));
1115 TrackEnd2s.push_back( BTracks.at(i).GetTrackPointV(1));
1116 TrackDir1s.push_back( BTracks.at(i).GetTrackDirectionV(0));
1117 TrackDir2s.push_back( BTracks.at(i).GetTrackDirectionV(1));
1120 std::vector<std::map<int,int> > TracksMeetAtPoints;
1121 std::vector<std::vector<TVector3> > MeetPoints;
1125 for(
size_t i=0; i!=BTracks.size(); ++i)
1127 for(
size_t j=0; j!=BTracks.size(); ++j)
1131 double impact, disti, distj;
1132 GetImpact(TrackEnd1s[i],TrackDir1s[i],TrackEnd1s[j],TrackDir1s[j], impact, disti, distj);
1140 bool ThisTrackAlreadyMet =
false;
1141 TVector3 ExtrapPoint1 = TrackEnd1s[i] + TrackDir1s[j].Unit()*disti;
1142 TVector3 ExtrapPoint2 = TrackEnd1s[j] + TrackDir1s[j].Unit()*distj;
1144 for(
size_t pt=0;
pt!=TracksMeetAtPoints.size(); ++
pt)
1146 if(TracksMeetAtPoints.at(
pt)[i]==-1)
1148 TracksMeetAtPoints.at(
pt)[j]=-1;
1149 MeetPoints.at(
pt).push_back(ExtrapPoint1);
1150 MeetPoints.at(
pt).push_back(ExtrapPoint2);
1151 ThisTrackAlreadyMet=
true;
1154 else if(TracksMeetAtPoints.at(
pt)[j]==-1)
1156 TracksMeetAtPoints.at(
pt)[i]=-1;
1157 MeetPoints.at(
pt).push_back(ExtrapPoint1);
1158 MeetPoints.at(
pt).push_back(ExtrapPoint2);
1159 ThisTrackAlreadyMet=
true;
1162 if(!ThisTrackAlreadyMet)
1164 size_t pt = TracksMeetAtPoints.size();
1165 TracksMeetAtPoints.push_back(std::map<int,int>());
1166 TracksMeetAtPoints.at(pt)[i]=-1;
1167 TracksMeetAtPoints.at(pt)[j]=-1;
1168 MeetPoints.push_back(std::vector<TVector3>());
1169 MeetPoints.at(pt).push_back(ExtrapPoint1);
1170 MeetPoints.at(pt).push_back(ExtrapPoint2);
1175 GetImpact(TrackEnd2s[i],TrackDir2s[i],TrackEnd2s[j],TrackDir2s[j], impact, disti, distj);
1182 bool ThisTrackAlreadyMet =
false;
1183 TVector3 ExtrapPoint1 = TrackEnd1s[i] + TrackDir2s[j].Unit()*disti;
1184 TVector3 ExtrapPoint2 = TrackEnd2s[j] + TrackDir2s[j].Unit()*distj;
1186 for(
size_t pt=0;
pt!=TracksMeetAtPoints.size(); ++
pt)
1188 if(TracksMeetAtPoints.at(
pt)[i]==1)
1190 TracksMeetAtPoints.at(
pt)[j]=1;
1191 MeetPoints.at(
pt).push_back(ExtrapPoint1);
1192 MeetPoints.at(
pt).push_back(ExtrapPoint2);
1193 ThisTrackAlreadyMet=
true;
1196 else if(TracksMeetAtPoints.at(
pt)[j]==1)
1198 TracksMeetAtPoints.at(
pt)[i]=1;
1199 MeetPoints.at(
pt).push_back(ExtrapPoint1);
1200 MeetPoints.at(
pt).push_back(ExtrapPoint2);
1201 ThisTrackAlreadyMet=
true;
1204 if(!ThisTrackAlreadyMet)
1206 size_t pt = TracksMeetAtPoints.size();
1207 TracksMeetAtPoints.push_back(std::map<int,int>());
1208 TracksMeetAtPoints.at(pt)[i]=1;
1209 TracksMeetAtPoints.at(pt)[j]=1;
1210 MeetPoints.push_back(std::vector<TVector3>());
1211 MeetPoints.at(pt).push_back(ExtrapPoint1);
1212 MeetPoints.at(pt).push_back(ExtrapPoint2);
1218 GetImpact(TrackEnd1s[i],TrackDir1s[i],TrackEnd2s[j],TrackDir2s[j], impact, disti, distj);
1225 bool ThisTrackAlreadyMet =
false;
1226 TVector3 ExtrapPoint1 = TrackEnd1s[i] + TrackDir2s[j].Unit()*disti;
1227 TVector3 ExtrapPoint2 = TrackEnd2s[j] + TrackDir2s[j].Unit()*distj;
1229 for(
size_t pt=0;
pt!=TracksMeetAtPoints.size(); ++
pt)
1231 if(TracksMeetAtPoints.at(
pt)[i]==-1)
1233 TracksMeetAtPoints.at(
pt)[j]=1;
1234 MeetPoints.at(
pt).push_back(ExtrapPoint1);
1235 MeetPoints.at(
pt).push_back(ExtrapPoint2);
1236 ThisTrackAlreadyMet=
true;
1239 else if(TracksMeetAtPoints.at(
pt)[j]==1)
1241 TracksMeetAtPoints.at(
pt)[i]=-1;
1242 MeetPoints.at(
pt).push_back(ExtrapPoint1);
1243 MeetPoints.at(
pt).push_back(ExtrapPoint2);
1244 ThisTrackAlreadyMet=
true;
1247 if(!ThisTrackAlreadyMet)
1249 size_t pt = TracksMeetAtPoints.size();
1250 TracksMeetAtPoints.push_back(std::map<int,int>());
1251 TracksMeetAtPoints.at(pt)[i]=-1;
1252 TracksMeetAtPoints.at(pt)[j]=1;
1253 MeetPoints.push_back(std::vector<TVector3>());
1254 MeetPoints.at(pt).push_back(ExtrapPoint1);
1255 MeetPoints.at(pt).push_back(ExtrapPoint2);
1266 for(
size_t pt=0;
pt!=TracksMeetAtPoints.size(); ++
pt)
1268 std::vector<int> TracksThisVertex;
1269 mf::LogVerbatim(
"BezierTrackerAlgorithm")<<
" Making track adjustments for vertex " <<
pt<<std::endl;
1270 TVector3 FinalMeetPt(0,0,0);
1271 for(
size_t i=0; i!=MeetPoints.at(
pt).size(); ++i)
1273 FinalMeetPt += MeetPoints.at(
pt).at(i);
1275 FinalMeetPt *= (1./float(MeetPoints.at(
pt).size()));
1277 for(
size_t i=0; i!=BTracks.size(); ++i)
1279 if(TracksMeetAtPoints.at(
pt)[i]==1)
1281 TracksThisVertex.push_back(i);
1282 TVector3 NewDirection = (FinalMeetPt - TrackEnd2s[i])*0.5;
1287 for(
size_t n=0;
n!=3; ++
n)
1289 NewPos[
n]=FinalMeetPt[
n]-NewDirection[
n];
1290 NewDir[
n]=NewDirection[
n];
1294 std::vector<recob::Seed> SeedCol = BTracks.at(i).GetSeedVector();
1295 SeedCol.at(SeedCol.size()-1) = NewSeed;
1298 else if(TracksMeetAtPoints.at(
pt)[i]==-1)
1300 TracksThisVertex.push_back(i);
1301 TVector3 NewDirection = -(FinalMeetPt - TrackEnd1s[i])*0.5;
1306 for(
size_t n=0;
n!=3; ++
n)
1308 NewPos[
n]=FinalMeetPt[
n] + NewDirection[
n];
1309 NewDir[
n]=NewDirection[
n];
1313 std::vector<recob::Seed> SeedCol = BTracks.at(i).GetSeedVector();
1314 SeedCol.at(0) = NewSeed;
1320 Mapping.push_back(TracksThisVertex);
1322 for(
size_t n=0;
n!=3; ++
n)
1323 VtxPoint[
n]=FinalMeetPt[
n];
1334 double lambda1 = ((t2pt-t1pt).Cross(t2dir)).Dot(t1dir.Cross(t2dir)) / (t1dir.Cross(t2dir)).Mag2();
1335 double lambda2 = ((t1pt-t2pt).Cross(t1dir)).Dot(t2dir.Cross(t1dir)) / (t2dir.Cross(t1dir)).Mag2();
1336 TVector3 c = t1pt + t1dir*lambda1 - t2pt - t2dir*lambda2;
1338 ImpactParam = c.Mag();
1339 Dist1 = lambda1 * t1dir.Mag();
1340 Dist2 = lambda2 * t2dir.Mag();
1347 return s1.size()>s2.size();
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
void MakeOverlapJoins(std::vector< trkf::BezierTrack > &BTracks, std::vector< art::PtrVector< recob::Hit > > &HitVecs, std::vector< std::vector< std::pair< int, int > > > &ClustersUsed)
void GetSeedDirProjected(recob::Seed const &TheSeed, std::vector< double > &WireCoord, std::vector< double > &TimeCoord)
bool BTrack_SeedCountComparator(std::vector< recob::Seed > const &s1, std::vector< recob::Seed > const &s2)
std::vector< recob::Seed > GetSeedVector()
double Dist2(const TVector2 &v1, const TVector2 &v2)
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
double fVertexExtrapDistance
geo::WireID WireID() const
Initial tdc tick for hit.
Declaration of signal hit object.
void SortTracksByLength(std::vector< trkf::BezierTrack > &BTracks, std::vector< art::PtrVector< recob::Hit > > &HitVecs, std::vector< std::vector< std::pair< int, int > > > &ClustersUsed)
WireID_t Wire
Index of the wire within its plane.
virtual ~BezierTrackerAlgorithm()
Definition of vertex object for LArSoft.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
double fDirectJoinDistance
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
std::vector< trkf::BezierTrack > MakeTracks(std::vector< std::vector< art::PtrVector< recob::Hit > > > &SortedHits, std::vector< art::PtrVector< recob::Hit > > &HitAssocs, std::vector< std::vector< std::pair< int, int > > > &ClustersUsed)
SpacePointAlg * GetSpacePointAlg() const
std::vector< TVector3 > fPitchDir
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
std::vector< double > fPlaneTimeOffsets
SeedFinderAlgorithm * fTheSeedFinder
trkf::BezierTrack JoinTracks(trkf::BezierTrack &BT1, trkf::BezierTrack &BT2)
void MakeVertexJoins(std::vector< trkf::BezierTrack > &BTracks, std::vector< recob::Vertex > &Vertices, std::vector< std::vector< int > > &Mapping)
void reconfigure(fhicl::ParameterSet const &pset)
void push_back(Ptr< U > const &p)
Service for finding 3D track seeds.
T get(std::string const &key) const
std::vector< std::vector< recob::Seed > > OrganizeSeedsIntoTracks(std::vector< recob::Seed > &AllSeeds, std::vector< art::PtrVector< recob::Hit > * > &AllHits, std::vector< art::PtrVector< recob::Hit > > &WhichHitsPerSeed, std::vector< std::vector< std::vector< int > > * > &OrgHits, std::vector< std::vector< std::vector< int > > > &WhichHitsPerTrack)
double GetDistance(Seed const &AnotherSeed) const
reference at(size_type n)
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
Provides recob::Track data product.
void AddPtrVectors(art::PtrVector< recob::Hit > &Receiever, art::PtrVector< recob::Hit > const &ToAdd)
void MakeDirectJoins(std::vector< trkf::BezierTrack > &BTracks, std::vector< art::PtrVector< recob::Hit > > &HitVecs, std::vector< std::vector< std::pair< int, int > > > &ClustersUsed)
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
std::vector< double > fWireZeroOffset
float PeakTime() const
Time of the signal peak, in tick units.
void CalculateGeometricalElements()
Utility object to perform functions of association.
std::vector< recob::Seed > GetSeedsFromUnSortedHits(art::PtrVector< recob::Hit > const &, std::vector< art::PtrVector< recob::Hit > > &, unsigned int StopAfter=0)
void FilterOverlapTracks(std::vector< trkf::BezierTrack > &BTracks, std::vector< art::PtrVector< recob::Hit > > &HitVecs, std::vector< std::vector< std::pair< int, int > > > &ClustersUsed)
trkf::SeedFinderAlgorithm * GetSeedFinderAlgorithm()
std::vector< TVector3 > fWireDir
void WireEndPoints(geo::WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
std::vector< double > fPitches
Planes which measure W (third view for Bo, MicroBooNE, etc).
std::vector< TVector3 > GetBezierPoints(recob::Seed const &s1, recob::Seed const &s2, int N=100)
Namespace collecting geometry-related classes utilities.
double fVertexImpactThreshold
void GetDirection(double *Dir, double *Err) const
BezierTrackerAlgorithm(fhicl::ParameterSet const &pset)
bool EvaluateOccupancy(recob::Seed &Seed1, recob::Seed &Seed2, double dThresh, std::vector< art::PtrVector< recob::Hit > * > &AllHits, std::vector< std::vector< std::vector< int > > * > &OrgHits, std::vector< uint32_t > &LowChan, std::vector< uint32_t > &HighChan, std::vector< std::vector< int > > &HitStatus, std::vector< std::vector< int > > &TheseHits)
void GetImpact(TVector3 t1pt, TVector3 t1dir, TVector3 t2pt, TVector3 t2dir, double &ImpactParam, double &Dist1, double &Dist2)
virtual double GetXTicksOffset(int p, int t, int c) const =0