11 #include <tracking/trackFindingCDC/legendre/quadtree/AxialHitQuadTreeProcessor.h>
13 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
24 using namespace TrackFindingCDC;
27 bool sameSign(
double n1,
double n2,
double n3,
double n4)
29 return ((n1 > 0 && n2 > 0 && n3 > 0 && n4 > 0) || (n1 < 0 && n2 < 0 && n3 < 0 && n4 < 0));
33 YSpan splitCurvSpan(
const YSpan& curvSpan,
int nodeLevel,
int lastLevel,
int j)
35 const float meanCurv = curvSpan[0] + (curvSpan[1] - curvSpan[0]) / 2.0;
36 const std::array<float, 3> binBounds{curvSpan[0], meanCurv, curvSpan[1]};
37 const float binWidth = binBounds[j + 1] - binBounds[j];
39 const bool standardBinning = (nodeLevel <= lastLevel - 7) or (std::fabs(meanCurv) <= 0.005);
40 if (standardBinning) {
42 float curv1 = binBounds[j];
43 float curv2 = binBounds[j + 1];
46 return {curv1, curv2};
52 if (nodeLevel < lastLevel - 5) {
54 float curv1 = binBounds[j] - binWidth / 4.;
55 float curv2 = binBounds[j + 1] + binWidth / 4.;
56 return {curv1, curv2};
59 float curv1 = binBounds[j] - binWidth / 8.;
60 float curv2 = binBounds[j + 1] + binWidth / 8.;
61 return {curv1, curv2};
69 std::vector<YSpan> spans{{curvSpan}};
71 std::vector<YSpan> nextSpans;
72 for (
int level = 1; level <= lastLevel; ++level) {
74 for (
const YSpan& span : spans) {
75 nextSpans.push_back(splitCurvSpan(span, level, lastLevel, 0));
76 nextSpans.push_back(splitCurvSpan(span, level, lastLevel, 1));
78 spans.swap(nextSpans);
81 std::vector<float> bounds;
82 for (
const YSpan& span : spans) {
83 bounds.push_back(span[0]);
84 bounds.push_back(span[1]);
87 assert(bounds.size() == std::pow(2, lastLevel));
94 static const int nBins = std::pow(2, maxLevel);
96 return trigonometricLookUpTable;
104 , m_cosSinLookupTable(&getCosSinLookupTable())
105 , m_localOrigin(0.0, 0.0)
106 , m_precisionFunction(precisionFunction)
112 const YSpan& curvSpan,
115 , m_cosSinLookupTable(cosSinLookupTable)
116 , m_localOrigin(localOrigin)
119 m_twoSidedPhaseSpace =
false;
125 if (node->
getLevel() <= 6)
return false;
128 const double nodeResolution = fabs(node->
getYMin() - node->
getYMax());
132 if (resolution >= nodeResolution)
return true;
140 const int nodeLevel = node->
getLevel();
142 const float meanCurv = std::fabs(node->
getYMax() + node->
getYMin()) / 2;
146 bool standardBinning = (nodeLevel <= lastLevel - 7) or (meanCurv <= 0.005);
148 if (standardBinning) {
155 return XYSpans({theta1, theta2}, {r1, r2});
161 if (nodeLevel < lastLevel - 5) {
166 long extension = pow(2, lastLevel - nodeLevel - 2);
169 if (theta1 < 0) theta1 = 0;
176 return XYSpans({theta1, theta2}, {r1, r2});
182 long extension = pow(2, lastLevel - nodeLevel - 3);
185 if (theta1 < 0) theta1 = 0;
192 return XYSpans({theta1, theta2}, {r1, r2});
204 const double& l = wireHit->getRefDriftLength();
208 using Quadlet = std::array<std::array<float, 2>, 2>;
213 float rMin = node->
getYMin() * r2 / 2;
214 float rMax = node->
getYMax() * r2 / 2;
217 long thetaMin = node->
getXMin();
218 long thetaMax = node->
getXMax();
223 float rHitMin = thetaVecMin.
dot(pos2D);
224 float rHitMax = thetaVecMax.
dot(pos2D);
227 float rHitMinRight = rHitMin - l;
228 float rHitMaxRight = rHitMax - l;
230 float rHitMinLeft = rHitMin + l;
231 float rHitMaxLeft = rHitMax + l;
234 distRight[0][0] = rMin - rHitMinRight;
235 distRight[0][1] = rMin - rHitMaxRight;
236 distRight[1][0] = rMax - rHitMinRight;
237 distRight[1][1] = rMax - rHitMaxRight;
239 distLeft[0][0] = rMin - rHitMinLeft;
240 distLeft[0][1] = rMin - rHitMaxLeft;
241 distLeft[1][0] = rMax - rHitMinLeft;
242 distLeft[1][1] = rMax - rHitMaxLeft;
246 if (not sameSign(distRight[0][0], distRight[0][1], distRight[1][0], distRight[1][1])) {
251 if (not sameSign(distLeft[0][0], distLeft[0][1], distLeft[1][0], distLeft[1][1])) {
256 float rHitMinExtr = thetaVecMin.
cross(pos2D);
257 float rHitMaxExtr = thetaVecMax.
cross(pos2D);
258 if (rHitMinExtr * rHitMaxExtr < 0.)
return checkExtremum(node, wireHit);
268 long thetaMin = node->
getXMin();
269 long thetaMax = node->
getXMax();
274 float rMinD = thetaVecMin.
cross(pos2D);
275 float rMaxD = thetaVecMax.
cross(pos2D);
278 if ((rMinD > 0) && (rMaxD * rMinD >= 0))
return true;
279 if ((rMaxD * rMinD < 0))
return true;
285 const double& l = wireHit->getRefDriftLength();
290 long thetaMin = node->
getXMin();
291 long thetaMax = node->
getXMax();
296 if (not pos2D.
isBetween(thetaVecMin, thetaVecMax))
return false;
299 double r = pos2D.
norm();
300 float rRight = r - l;
304 float rMin = node->
getYMin() * r2 / 2;
305 float rMax = node->
getYMax() * r2 / 2;
307 bool crossesRight = (rMin - rRight) * (rMax - rRight) < 0;
308 bool crossesLeft = (rMin - rLeft) * (rMax - rLeft) < 0;
309 return crossesRight or crossesLeft;
314 static int nevent(0);
316 TCanvas* canv =
new TCanvas(
"canv",
"legendre transform", 0, 0, 1200, 600);
318 TGraph* dummyGraph =
new TGraph();
319 dummyGraph->SetPoint(1, -3.1415, 0);
320 dummyGraph->SetPoint(2, 3.1415, 0);
321 dummyGraph->Draw(
"AP");
322 dummyGraph->GetXaxis()->SetTitle(
"#theta");
323 dummyGraph->GetYaxis()->SetTitle(
"#rho");
324 dummyGraph->GetXaxis()->SetRangeUser(-3.1415, 3.1415);
325 dummyGraph->GetYaxis()->SetRangeUser(-0.02, 0.15);
328 const double& l = wireHit->getRefDriftLength();
330 double x = pos2D.
x();
331 double y = pos2D.
y();
334 TF1* concaveHitLegendre =
new TF1(
"concaveHitLegendre",
"2*([0]/[3])*cos(x) + 2*([1]/[3])*sin(x) + 2*([2]/[3])", -3.1415, 3.1415);
335 TF1* convexHitLegendre =
new TF1(
"convexHitLegendre",
"2*([0]/[3])*cos(x) + 2*([1]/[3])*sin(x) - 2*([2]/[3])", -3.1415, 3.1415);
336 concaveHitLegendre->SetLineWidth(1);
337 convexHitLegendre->SetLineWidth(1);
338 concaveHitLegendre->SetLineColor(color);
339 convexHitLegendre->SetLineColor(color);
341 concaveHitLegendre->SetParameters(x, y, l, r2);
342 convexHitLegendre->SetParameters(x, y, l, r2);
343 concaveHitLegendre->Draw(
"CSAME");
344 convexHitLegendre->Draw(
"CSAME");
348 canv->Print(Form(
"legendreHits_%i.png", nevent));
356 std::vector<const CDCWireHit*> hits;
358 const CDCWireHit* wireHit = item->getPointer();
359 hits.push_back(wireHit);