10#include <tracking/trackFindingCDC/legendre/quadtree/QuadTreeNode.h>
11#include <tracking/trackFindingCDC/legendre/quadtree/QuadTreeItem.h>
13#include <tracking/trackingUtilities/utilities/Algorithms.h>
15#include <framework/logging/Logger.h>
31 namespace TrackingUtilities {
34 namespace TrackFindingCDC {
42 template<
typename AX,
typename AY,
class AData>
82 bool debugOutput =
false)
113 void seed(
const std::vector<AData*>& datas)
116 for (AData* data : datas) {
126 std::vector<QuadTree*> nextSeededTrees;
128 for (
int level = 0; level <
m_seedLevel; ++level) {
130 if (node->getChildren().empty()) {
133 for (
QuadTree& child : node->getChildren()) {
134 nextSeededTrees.push_back(&child);
138 nextSeededTrees.clear();
149 seededTree->reserveItems(
m_items.size());
162 std::vector<const TrackingUtilities::CDCWireHit*> result;
164 for (
Item* item : seededTree->getItems()) {
165 result.push_back(item->getPointer());
168 std::sort(result.begin(), result.end());
169 result.erase(std::unique(result.begin(), result.end()), result.end());
181 fill(candidateReceiver, nHitsThreshold, std::numeric_limits<AY>::max());
193 std::sort(quadTrees.begin(), quadTrees.end(), [](
const QuadTree * quadTree1,
const QuadTree * quadTree2) {
194 return quadTree1->getNItems() > quadTree2->getNItems();
198 erase_remove_if(tree->getItems(), [](
Item * hit) { return hit->isUsed(); });
199 fillGivenTree(tree, candidateReceiver, nHitsThreshold, yLimit);
213 if (node->
getNItems() < nItemsThreshold) {
236 std::array<QuadTree*, c_maxNChildren> children;
239 B2ASSERT(
"More children than the quad tree processor supports", nChildren <
c_maxNChildren);
240 children[nChildren++] = &child;
243 return lhs->
getNItems() < rhs->getNItems();
247 for (
int nRemaining = nChildren; nRemaining > 0; --nRemaining) {
248 auto itHeaviestChild =
249 std::max_element(children.begin(), children.begin() + nRemaining, compareNItems);
250 QuadTree* heaviestChild = *itHeaviestChild;
252 std::move(itHeaviestChild + 1, children.begin() + nRemaining, itHeaviestChild);
255 erase_remove_if(heaviestChild->
getItems(), [&](
Item * hit) { return hit->isUsed(); });
256 this->
fillGivenTree(heaviestChild, candidateReceiver, nItemsThreshold, yLimit);
267 for (
int i = 0; i < node->
getXNbins(); ++i) {
268 for (
int j = 0; j < node->
getYNbins(); ++j) {
270 const XSpan& xSpan = xySpans.first;
271 const YSpan& ySpan = xySpans.second;
284 const size_t neededSize = items.size();
288 child.reserveItems(neededSize);
303 const std::vector<Item*>& foundItems = node->
getItems();
304 std::vector<AData*> candidate;
305 candidate.reserve(foundItems.size());
307 for (
Item* item : foundItems) {
309 candidate.push_back(item->getPointer());
312 candidateReceiver(candidate, node);
330 return XYSpans({xMin, xMax}, {yMin, yMax});
352 const std::vector<Item*>& items)
354 for (
Item* item : items) {
355 if (item->isUsed())
continue;
358 if (
isInNode(node, item->getPointer())) {
359 node->insertItem(item);
395 for (
const 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.
virtual void insertItemsInNodes(const std::vector< QuadTree * > &nodes, const std::vector< Item * > &items)
Insert each of the given items into every one of the given nodes it belongs to.
QuadTreeNode< AX, AY, Item > QuadTree
The used QuadTree.
static void callResultFunction(QuadTree *node, const CandidateReceiver &candidateReceiver)
When a node is accepted as a result, we extract a vector with the items (back transformed to AData*) ...
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.
std::vector< Item * > m_itemPtrs
Reusable buffer with pointers to all items - used to seed the tree.
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< QuadTree * > m_childPtrs
Reusable buffer with pointers to the children of the node currently being filled.
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.
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...
static const int c_maxNChildren
Upper bound on the number of children of a node - they are kept on the stack.
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.