8#include <tracking/trackFindingCDC/legendre/quadtree/AxialHitQuadTreeProcessor.h>
10#include <tracking/trackingUtilities/eventdata/hits/CDCWireHit.h>
21using namespace TrackFindingCDC;
22using namespace TrackingUtilities;
25 bool sameSign(
double n1,
double n2,
double n3,
double n4)
27 return ((n1 > 0 && n2 > 0 && n3 > 0 && n4 > 0) || (n1 < 0 && n2 < 0 && n3 < 0 && n4 < 0));
30 using YSpan = AxialHitQuadTreeProcessor::YSpan;
31 YSpan splitCurvSpan(
const YSpan& curvSpan,
int nodeLevel,
int lastLevel,
int j)
33 const float meanCurv = curvSpan[0] + (curvSpan[1] - curvSpan[0]) / 2.0;
34 const std::array<float, 3> binBounds{curvSpan[0], meanCurv, curvSpan[1]};
35 const float binWidth = binBounds[j + 1] - binBounds[j];
37 const bool standardBinning = (nodeLevel <= lastLevel - 7) or (std::fabs(meanCurv) <= 0.005);
38 if (standardBinning) {
40 float curv1 = binBounds[j];
41 float curv2 = binBounds[j + 1];
44 return {curv1, curv2};
50 if (nodeLevel < lastLevel - 5) {
52 float curv1 = binBounds[j] - binWidth / 4.;
53 float curv2 = binBounds[j + 1] + binWidth / 4.;
54 return {curv1, curv2};
57 float curv1 = binBounds[j] - binWidth / 8.;
58 float curv2 = binBounds[j + 1] + binWidth / 8.;
59 return {curv1, curv2};
67 std::vector<YSpan> spans{{curvSpan}};
69 std::vector<YSpan> nextSpans;
70 for (
int level = 1; level <= lastLevel; ++level) {
72 for (
const YSpan& span : spans) {
73 nextSpans.push_back(splitCurvSpan(span, level, lastLevel, 0));
74 nextSpans.push_back(splitCurvSpan(span, level, lastLevel, 1));
76 spans.swap(nextSpans);
79 std::vector<float> bounds;
80 for (
const YSpan& span : spans) {
81 bounds.push_back(span[0]);
82 bounds.push_back(span[1]);
85 assert(bounds.size() == std::pow(2, lastLevel));
92 static const int nBins = std::pow(2, maxLevel);
94 return trigonometricLookUpTable;
110 const YSpan& curvSpan,
113, m_localOrigin(localOrigin)
114, m_cosSinLookupTable(cosSinLookupTable)
117 m_twoSidedPhaseSpace =
false;
123 if (node->
getLevel() <= 6)
return false;
126 const double nodeResolution = fabs(node->
getYMin() - node->
getYMax());
130 if (resolution >= nodeResolution)
return true;
138 const int nodeLevel = node->
getLevel();
140 const float meanCurv = std::fabs(node->
getYMax() + node->
getYMin()) / 2;
144 bool standardBinning = (nodeLevel <= lastLevel - 7) or (meanCurv <= 0.005);
146 if (standardBinning) {
153 return XYSpans({theta1, theta2}, {r1, r2});
159 if (nodeLevel < lastLevel - 5) {
164 long extension = pow(2, lastLevel - nodeLevel - 2);
167 if (theta1 < 0) theta1 = 0;
174 return XYSpans({theta1, theta2}, {r1, r2});
180 long extension = pow(2, lastLevel - nodeLevel - 3);
183 if (theta1 < 0) theta1 = 0;
190 return XYSpans({theta1, theta2}, {r1, r2});
202 const double& l = wireHit->getRefDriftLength();
206 using Quadlet = std::array<std::array<float, 2>, 2>;
211 float rMin = node->
getYMin() * r2 / 2;
212 float rMax = node->
getYMax() * r2 / 2;
215 long thetaMin = node->
getXMin();
216 long thetaMax = node->
getXMax();
221 float rHitMin = thetaVecMin.
dot(pos2D);
222 float rHitMax = thetaVecMax.
dot(pos2D);
225 float rHitMinRight = rHitMin - l;
226 float rHitMaxRight = rHitMax - l;
228 float rHitMinLeft = rHitMin + l;
229 float rHitMaxLeft = rHitMax + l;
232 distRight[0][0] = rMin - rHitMinRight;
233 distRight[0][1] = rMin - rHitMaxRight;
234 distRight[1][0] = rMax - rHitMinRight;
235 distRight[1][1] = rMax - rHitMaxRight;
237 distLeft[0][0] = rMin - rHitMinLeft;
238 distLeft[0][1] = rMin - rHitMaxLeft;
239 distLeft[1][0] = rMax - rHitMinLeft;
240 distLeft[1][1] = rMax - rHitMaxLeft;
244 if (not sameSign(distRight[0][0], distRight[0][1], distRight[1][0], distRight[1][1])) {
249 if (not sameSign(distLeft[0][0], distLeft[0][1], distLeft[1][0], distLeft[1][1])) {
254 float rHitMinExtr = thetaVecMin.
cross(pos2D);
255 float rHitMaxExtr = thetaVecMax.
cross(pos2D);
256 if (rHitMinExtr * rHitMaxExtr < 0.)
return checkExtremum(node, wireHit);
266 long thetaMin = node->
getXMin();
267 long thetaMax = node->
getXMax();
272 float rMinD = thetaVecMin.
cross(pos2D);
273 float rMaxD = thetaVecMax.
cross(pos2D);
276 if ((rMinD > 0) && (rMaxD * rMinD >= 0))
return true;
277 if ((rMaxD * rMinD < 0))
return true;
283 const double& l = wireHit->getRefDriftLength();
288 long thetaMin = node->
getXMin();
289 long thetaMax = node->
getXMax();
294 if (not pos2D.
isBetween(thetaVecMin, thetaVecMax))
return false;
297 double r = pos2D.
norm();
298 float rRight = r - l;
302 float rMin = node->
getYMin() * r2 / 2;
303 float rMax = node->
getYMax() * r2 / 2;
305 bool crossesRight = (rMin - rRight) * (rMax - rRight) < 0;
306 bool crossesLeft = (rMin - rLeft) * (rMax - rLeft) < 0;
307 return crossesRight or crossesLeft;
312 static int nevent(0);
314 TCanvas* canv =
new TCanvas(
"canv",
"legendre transform", 0, 0, 1200, 600);
316 TGraph* dummyGraph =
new TGraph();
317 dummyGraph->SetPoint(1, -M_PI, 0);
318 dummyGraph->SetPoint(2, M_PI, 0);
319 dummyGraph->Draw(
"AP");
320 dummyGraph->GetXaxis()->SetTitle(
"#theta");
321 dummyGraph->GetYaxis()->SetTitle(
"#rho");
322 dummyGraph->GetXaxis()->SetRangeUser(-M_PI, M_PI);
323 dummyGraph->GetYaxis()->SetRangeUser(-0.02, 0.15);
326 const double& l = wireHit->getRefDriftLength();
328 double x = pos2D.
x();
329 double y = pos2D.
y();
332 TF1* concaveHitLegendre =
new TF1(
"concaveHitLegendre",
"2*([0]/[3])*cos(x) + 2*([1]/[3])*sin(x) + 2*([2]/[3])", -M_PI, M_PI);
333 TF1* convexHitLegendre =
new TF1(
"convexHitLegendre",
"2*([0]/[3])*cos(x) + 2*([1]/[3])*sin(x) - 2*([2]/[3])", -M_PI, M_PI);
334 concaveHitLegendre->SetLineWidth(1);
335 convexHitLegendre->SetLineWidth(1);
336 concaveHitLegendre->SetLineColor(color);
337 convexHitLegendre->SetLineColor(color);
339 concaveHitLegendre->SetParameters(x, y, l, r2);
340 convexHitLegendre->SetParameters(x, y, l, r2);
341 concaveHitLegendre->Draw(
"CSAME");
342 convexHitLegendre->Draw(
"CSAME");
346 canv->Print(Form(
"legendreHits_%i.png", nevent));
354 std::vector<const CDCWireHit*> hits;
356 const CDCWireHit* wireHit = item->getPointer();
357 hits.push_back(wireHit);
XYSpans createChild(QuadTree *node, int i, int j) const final
Return the new ranges.
const double c_curlCurv
The curvature above which the trajectory is considered a curler.
bool m_twoSidedPhaseSpace
Indicator whether the two sided phases space insertion check should be used This option should automa...
void drawHits(std::vector< const TrackingUtilities::CDCWireHit * > hits, unsigned int color=46) const
Draw QuadTree node.
TrackingUtilities::Vector2D m_localOrigin
Local origin on which the phase space coordinates are centered.
bool checkDerivative(QuadTree *node, const TrackingUtilities::CDCWireHit *wireHit) const
Check derivative of the sinogram.
bool isLeaf(QuadTree *node) const final
lastLevel depends on curvature of the track candidate
bool isInNode(QuadTree *node, const TrackingUtilities::CDCWireHit *wireHit) const final
Check whether hit belongs to the quadtree node:
bool checkExtremum(QuadTree *node, const TrackingUtilities::CDCWireHit *wireHit) const
Checks whether extreme point is located within QuadTree node's ranges.
AxialHitQuadTreeProcessor(int lastLevel, int seedLevel, const XYSpans &ranges, PrecisionUtil::PrecisionFunction precisionFunction)
Constructor.
PrecisionUtil::PrecisionFunction m_precisionFunction
Lambda which holds resolution function for the quadtree.
static const TrackingUtilities::LookupTable< TrackingUtilities::Vector2D > & getCosSinLookupTable()
Get the standard lookup table containing equally spaces unit vectors (cos, sin)
void drawNode(QuadTree *node) const
Draw QuadTree node.
static std::vector< float > createCurvBound(YSpan curvSpan, int lastLevel)
Constructs an array with the curvature bounds as generated by the default bin divisions.
const TrackingUtilities::LookupTable< TrackingUtilities::Vector2D > * m_cosSinLookupTable
Pinned lookup table for precomputed cosine and sine values.
static constexpr int getLookupGridLevel()
Returns desired deepness of the trigonometrical lookup table. Used as template parameter for the Trig...
std::function< double(double)> PrecisionFunction
Function type which is used for resolution calculations (resolution=f(curvature)) Takes a curvature v...
std::vector< AItem * > & getItems()
Get items from node.
AY getYBinWidth(int iBin)
Getter for the width of the iBin bin in "r" direction.
AX getXMax() const
Get maximal "Theta" value of the node.
AY getYMax() const
Get maximal "r" value of the node.
AY getYMin() const
Get minimal "r" value of the node.
int getLevel() const
Returns level of the node in tree (i.e., how much ancestors the node has)
AX getXLowerBound(int iBin) const
Get lower "Theta" value of given bin.
AY getYUpperBound(int iBin) const
Get upper "r" value of given bin.
AY getYLowerBound(int iBin) const
Get lower "r" value of given bin.
AX getXMin() const
Get minimal "Theta" value of the node.
AX getXUpperBound(int iBin) const
Get upper "Theta" value of given bin.
QuadTreeNode< long, float, Item > QuadTree
std::pair< XSpan, YSpan > XYSpans
QuadTreeProcessor(int lastLevel, int seedLevel, const XYSpans &xySpans, bool debugOutput=false)
typename QuadTree::YSpan YSpan
QuadTreeItem< const TrackingUtilities::CDCWireHit > Item
std::unique_ptr< QuadTree > m_quadTree
Class representing a hit wire in the central drift chamber.
Class which holds precomputed values of a function.
int getNPoints() const
Return the number of finite sampling points in this lookup table.
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
double dot(const Vector2D &rhs) const
Calculates the two dimensional dot product.
double cross(const Vector2D &rhs) const
Calculated the two dimensional cross product.
double x() const
Getter for the x coordinate.
bool isBetween(const Vector2D &lower, const Vector2D &upper) const
Checks if this vector is between two other vectors Between means here that when rotating the lower ve...
double normSquared() const
Calculates .
double y() const
Getter for the y coordinate.
double norm() const
Calculates the length of the vector.
static Vector2D Phi(const double phi)
Constructs a unit vector with azimuth angle equal to phi.
bool sameSign(double expected, double actual)
Predicate checking that two values have the same sign.
Abstract base class for different kinds of events.