13 #include <FairLogger.h>
15 #include <Math/Point3D.h>
16 #include <Math/Vector2D.h>
17 #include <Math/Vector2Dfwd.h>
18 #include <Math/Vector3D.h>
56 if (!circularTracks.empty()) {
58 auto &hits = circularTracks.at(0).GetHitArray();
63 auto radius = circle->GetRadius();
70 std::vector<double> whit;
71 std::vector<double> arclength;
73 auto arclengthGraph = std::make_unique<TGraph>();
75 auto posPCA = hits.at(0)->GetPosition();
76 auto refPosOnCircle = posPCA - center;
77 auto refAng = refPosOnCircle.Phi();
79 std::vector<AtHit> thetaHits;
85 int lastYSign =
GetSign(refPosOnCircle.Y());
87 for (
size_t i = 0; i < hits.size(); ++i) {
89 auto pos = hits.at(i)->GetPosition();
90 auto posOnCircle = pos - center;
91 auto angleHit = posOnCircle.Phi();
94 int currYSign =
GetSign(posOnCircle.Y());
99 if (posOnCircle.X() < 0 && lastYSign != currYSign) {
100 numYCross -= currYSign;
102 lastYSign = currYSign;
103 angleHit += 2 * M_PI * numYCross;
105 whit.push_back(angleHit);
106 arclength.push_back((radius * (refAng - whit.at(i))));
108 arclengthGraph->SetPoint(arclengthGraph->GetN(), arclength.at(i), pos.Z());
111 LOG(debug2) << posOnCircle.X() <<
" " << posOnCircle.Y() <<
" " << pos.Z() <<
" "
112 << hits.at(i)->GetTimeStamp() <<
" " << arclength.back() <<
"\n";
115 Double_t xPos = arclength.at(i);
116 Double_t yPos = pos.Z();
117 Double_t zPos = i * 1E-19;
119 thetaHits.emplace_back(i, hits.at(i)->GetPadNum(),
XYZPoint(xPos, yPos, zPos), hits.at(i)->GetCharge());
130 Double_t angle = 0.0;
135 if (thetaHits.size() > 0) {
137 std::vector<AtTrack> thetaTracks;
146 if (thetaTracks.size() > 0) {
151 <<
" hits. Fit " << thetaTracks[0].GetHitArray().size() <<
"/" << thetaHits.size()
152 <<
" hits in first of " << thetaTracks.size() <<
" tracks";
154 auto dirTheta = line->GetDirection();
159 if (dir2D.X() * dir2D.Y() < 0)
164 if (dir2D.X() != 0) {
165 angle = acos(
sign * fabs(dir2D.Y())) * TMath::RadToDeg();
168 LOG(info) <<
"Setting theta geo to: " << angle <<
" with ransac direction: " << dir2D;
169 for (
int i = 1; i < thetaTracks.size(); ++i) {
171 auto ranDir =
ROOT::Math::XYVector(ranLine->GetDirection().X(), ranLine->GetDirection().Y()).Unit();
172 LOG(info) <<
"RANSAC direction " << i <<
" with " << thetaTracks[i].GetHitArray().size() <<
"/"
173 << thetaHits.size() <<
": " << ranDir;
176 auto temp2 = posPCA - center;
177 phi0 = TMath::ATan2(temp2.Y(), temp2.X());
186 <<
" hits does not have enough theta hits to get angle";
189 }
catch (std::exception &e) {
191 std::cout <<
" AtPRA::SetTrackInitialParameters - Exception caught : " << e.what() <<
"\n";
197 Double_t
fitf(Double_t *x, Double_t *par)
200 return par[0] + par[1] * x[0];
207 std::cout <<
" === Prunning track : " << track.
GetTrackID() <<
"\n";
208 std::cout <<
" = Hit Array size : " << hitArray.size() <<
"\n";
210 for (
auto iHit = 0; iHit < hitArray.size(); ++iHit) {
213 bool isNoise = kNN(hitArray, *hitArray.at(iHit), fKNN);
217 hitArray.erase(hitArray.begin() + iHit);
219 }
catch (std::exception &e) {
221 std::cout <<
" AtPRA::PruneTrack - Exception caught : " << e.what() <<
"\n";
225 std::cout <<
" = Hit Array size after prunning : " << hitArray.size() <<
"\n";
231 std::vector<Double_t> distances;
232 distances.reserve(hits.size());
234 std::for_each(hits.begin(), hits.end(), [&distances, &hitRef](
const std::unique_ptr<AtHit> &hit) {
235 distances.push_back(TMath::Sqrt((hitRef.GetPosition() - hit->GetPosition()).Mag2()));
238 std::sort(distances.begin(), distances.end(), [](Double_t a, Double_t b) { return a < b; });
241 Double_t stdDev = 0.0;
247 for (
auto i = 0; i < k; ++i)
248 mean += distances.at(i);
253 for (
auto i = 0; i < k; ++i)
254 stdDev += TMath::Power((distances.at(i) -
mean), 2);
256 stdDev = TMath::Sqrt(stdDev / k);
259 Double_t T =
mean + stdDev * fStdDevMulkNN;
261 return (T < fkNNDist) ? false :
true;