10#include <tracking/trackFindingCDC/legendre/quadtree/QuadTreeNode.h>
11#include <tracking/trackFindingCDC/legendre/quadtree/QuadTreeItem.h>
13#include <tracking/trackingUtilities/utilities/Algorithms.h>
28 namespace TrackingUtilities {
31 namespace TrackFindingCDC {
39 template<
typename AX,
typename AY,
class AData>
75 bool debugOutput =
false)
106 void seed(
const std::vector<AData*>& datas)
109 for (AData* data : datas) {
119 std::vector<QuadTree*> nextSeededTrees;
121 for (
int level = 0; level <
m_seedLevel; ++level) {
123 if (node->getChildren().empty()) {
126 for (
QuadTree& child : node->getChildren()) {
127 nextSeededTrees.push_back(&child);
131 nextSeededTrees.clear();
136 seededTree->reserveItems(
m_items.size());
139 if (item.isUsed())
continue;
140 if (
isInNode(seededTree, item.getPointer())) {
141 seededTree->insertItem(&item);
154 std::vector<const TrackingUtilities::CDCWireHit*> result;
156 for (
Item* item : seededTree->getItems()) {
157 result.push_back(item->getPointer());
160 std::sort(result.begin(), result.end());
161 result.erase(std::unique(result.begin(), result.end()), result.end());
173 fill(candidateReceiver, nHitsThreshold, std::numeric_limits<AY>::max());
185 std::sort(quadTrees.begin(), quadTrees.end(), [](
QuadTree * quadTree1,
QuadTree * quadTree2) {
186 return quadTree1->getNItems() > quadTree2->getNItems();
190 erase_remove_if(tree->getItems(), [](
Item * hit) { return hit->isUsed(); });
191 fillGivenTree(tree, candidateReceiver, nHitsThreshold, yLimit);
205 if (node->
getNItems() < nItemsThreshold) {
227 std::vector<QuadTree*> children;
229 children.push_back(&child);
232 return lhs->
getNItems() < rhs->getNItems();
236 const int nChildren = children.size();
237 for (
int iChild = 0; iChild < nChildren; ++iChild) {
238 auto itHeaviestChild = std::max_element(children.begin(), children.end(), compareNItems);
239 QuadTree* heaviestChild = *itHeaviestChild;
240 children.erase(itHeaviestChild);
243 erase_remove_if(heaviestChild->
getItems(), [&](
Item * hit) { return hit->isUsed(); });
244 this->
fillGivenTree(heaviestChild, candidateReceiver, nItemsThreshold, yLimit);
254 for (
int i = 0; i < node->
getXNbins(); ++i) {
255 for (
int j = 0; j < node->
getYNbins(); ++j) {
257 const XSpan& xSpan = xySpans.first;
258 const YSpan& ySpan = xySpans.second;
270 const size_t neededSize = 2 * items.size();
272 child.reserveItems(neededSize);
275 for (
Item* item : items) {
276 if (item->isUsed())
continue;
279 if (
isInNode(&child, item->getPointer())) {
280 child.insertItem(item);
293 const std::vector<Item*>& foundItems = node->
getItems();
294 std::vector<AData*> candidate;
295 candidate.reserve(foundItems.size());
297 for (
Item* item : foundItems) {
299 candidate.push_back(item->getPointer());
302 candidateReceiver(candidate, node);
320 return XYSpans({xMin, xMax}, {yMin, yMax});
362 for (
QuadTree& childNode : children) {
This class serves as a wrapper around all things that should go into a QuadTree.
Class which holds quadtree structure.
Children & getChildren()
Returns the children structure of this node.
std::vector< AItem * > & getItems()
Get items from node.
std::vector< This > Children
AY getYMax() const
Get maximal "r" value of the node.
std::array< AY, 2 > YSpan
void setFilled()
Set status of node to "filled" (children nodes has been filled)
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.
std::array< AX, 2 > XSpan
AY getYLowerBound(int iBin) const
Get lower "r" value of given bin.
bool checkFilled() const
Check whether node has been processed, i.e.
int getNItems() const
Check if the node passes threshold on number of hits.
constexpr int getXNbins() const
Get number of bins in "Theta" direction.
constexpr int getYNbins() const
Get number of bins in "r" direction.
AX getXUpperBound(int iBin) const
Get upper "Theta" value of given bin.
void fill(const CandidateReceiver &candidateReceiver, int nHitsThreshold, float yLimit)
Fill vector of QuadTree instances with hits.
QuadTreeNode< AX, AY, Item > QuadTree
The used QuadTree.
typename QuadTree::Children QuadTreeChildren
Alias for the QuadTree Children.
void createChildren(QuadTree *node, QuadTreeChildren &m_children) const
Creates the sub node of a given node.
void fillChildren(QuadTree *node, const std::vector< Item * > &items)
This function is called by fillGivenTree and fills the items into the corresponding children.
int m_lastLevel
The last level to be filled.
void fillGivenTree(QuadTree *node, const CandidateReceiver &candidateReceiver, int nItemsThreshold, AY yLimit)
Internal function to do the real quad tree search: fill the nodes, check which of the n*m bins we nee...
virtual ~QuadTreeProcessor()
Destructor deletes the quad tree.
const std::map< std::pair< AX, AY >, std::vector< Item * > > & getDebugInformation() const
Return the debug information if collected.
std::pair< XSpan, YSpan > XYSpans
This pair of spans describes the span of a node.
QuadTreeProcessor(int lastLevel, int seedLevel, const XYSpans &xySpans, bool debugOutput=false)
Constructor is very simple.
std::vector< QuadTree * > m_seededTrees
Vector of QuadTrees QuadTree instances (which are filled in the vector) cover the whole Legendre phas...
bool m_debugOutput
A flag to control the creation of the debug output.
int getLastLevel() const
Return the parameter last level.
virtual XYSpans createChild(QuadTree *node, int iX, int iY) const
Implement that function if you want to provide a new processor.
virtual bool isLeaf(QuadTree *node) const
Function which checks if given node is leaf Implemented as virtual to keep possibility of changing la...
typename QuadTree::XSpan XSpan
This pair describes the span in X for a node.
std::deque< Item > m_items
Storage space for the items that are referenced by the quad tree nodes.
std::vector< AData * > getAssignedItems()
Get items that have been assigned to the seed level The returned elements are unique even if items ar...
typename QuadTree::YSpan YSpan
This pair describes the span in Y for a node.
void fill(const CandidateReceiver &candidateReceiver, int nHitsThreshold)
Start filling the already created tree.
void clear()
Delete all the QuadTreeItems in the tree and clear the tree.
void callResultFunction(QuadTree *node, const CandidateReceiver &candidateReceiver) const
When a node is accepted as a result, we extract a vector with the items (back transformed to AData*) ...
int m_seedLevel
The first level to be filled, effectively skip forward to this higher granularity level.
void seed(const std::vector< AData * > &datas)
Fill in the items in the given vector.
std::function< void(const std::vector< AData * > &, QuadTree *)> CandidateReceiver
This lambda function can be used for postprocessing.
QuadTreeItem< AData > Item
The QuadTree will only see items of this type.
virtual bool isInNode(QuadTree *node, AData *item) const =0
Implement that function if you want to provide a new processor.
std::map< std::pair< AX, AY >, std::vector< Item * > > m_debugOutputMap
The calculated debug map.
virtual void afterFillDebugHook(QuadTreeChildren &children)
Override that function if you want to receive debug output whenever the children of a node are filled...
std::unique_ptr< QuadTree > m_quadTree
The quad tree we work with.
Class representing a hit wire in the central drift chamber.
Abstract base class for different kinds of events.