Belle II Software development
OverlapResolver.icc.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <tracking/ckf/general/findlets/OverlapResolver.dcl.h>
11
12#include <tracking/ckf/general/utilities/CKFFunctors.h>
13
14#include <tracking/trackingUtilities/utilities/Functional.h>
15#include <tracking/trackingUtilities/numerics/WeightComperator.h>
16#include <tracking/trackingUtilities/utilities/Algorithms.h>
17#include <tracking/trackingUtilities/utilities/VectorRange.h>
18#include <tracking/trackingUtilities/utilities/StringManipulation.h>
19
20#include <framework/core/ModuleParam.h>
21#include <framework/logging/Logger.h>
22
23#include <type_traits>
24#include <utility>
25
26namespace Belle2 {
31
32 namespace overlapResolverDetail {
34 * Type trait detecting whether a type provides a callable const getArrayIndex() member.
35 * This is the primary template, selected when T has no getArrayIndex() member.
36 */
37 template<class T, class = void>
38 struct HasGetArrayIndex : std::false_type {};
39
40 /**
41 * Specialization selected when T exposes a const getArrayIndex() member.
42 */
43 template<class T>
44struct HasGetArrayIndex<T, std::void_t<decltype(std::declval<const T&>().getArrayIndex())>> : std::true_type {};
45 }
46
47 template<class AFilter>
52
54 template<class AFilter>
55 void OverlapResolver<AFilter>::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
56 {
57 m_filter.exposeParameters(moduleParamList, prefix);
58
59 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "enableOverlapResolving"),
61 "Enable the overlap resolving.",
63 moduleParamList->addParameter(TrackingUtilities::prefixed(prefix, "useBestNInSeed"),
65 "In seed mode, use only the best seeds.",
67 }
68
69 template<class AFilter>
70 void OverlapResolver<AFilter>::apply(std::vector<typename AFilter::Object>& results,
71 std::vector<typename AFilter::Object>& filteredResults)
72 {
73 if (not m_param_enableOverlapResolving or results.empty()) {
74 std::swap(results, filteredResults);
75 return;
76 }
77
78 // The seed ordering below relies on getSeed()->getArrayIndex(); require it explicitly
79 // so a future instantiation with an unsuitable seed type fails with a clear message.
80 using SeedType = std::remove_cv_t<std::remove_pointer_t<
81 decltype(std::declval<typename AFilter::Object>().getSeed())>>;
83 "OverlapResolver orders seed groups by getSeed()->getArrayIndex() to keep the "
84 "order reproducible; the result seed type must provide a getArrayIndex() method.");
85
86 // Sort results by seed, as it makes the next operations faster.
87 // Order by the seed's array index rather than its heap address.
88 // Note that a seed here is a RecoTrack* from a StoreArray, so getArrayIndex() is well defined.
89 std::stable_sort(results.begin(), results.end(),
90 [](const typename AFilter::Object & lhs, const typename AFilter::Object & rhs) {
91 return lhs.getSeed()->getArrayIndex() < rhs.getSeed()->getArrayIndex();
92 });
93
94 // resolve overlaps in each seed separately
95 const auto& groupedBySeed = TrackingUtilities::adjacent_groupby(results.begin(), results.end(), SeedGetter());
96 for (const TrackingUtilities::VectorRange<Object>& resultsWithSameSeed : groupedBySeed) {
97
98 m_resultsWithWeight.clear();
99 for (Object& result : resultsWithSameSeed) {
100 TrackingUtilities::Weight weight = m_filter(result);
101 if (std::isnan(weight)) {
102 continue;
103 }
104 m_resultsWithWeight.emplace_back(&result, weight);
105 }
106
107 if (not m_resultsWithWeight.empty()) {
108 // sort results so that 'std::max' below picks path with highest weight if multiple paths have same size
109 std::sort(m_resultsWithWeight.begin(), m_resultsWithWeight.end(), TrackingUtilities::GreaterWeight());
110
111 const unsigned int useBestNResults = std::min(m_resultsWithWeight.size(), m_param_useBestNInSeed);
112 const auto& lastItemToUse = std::next(m_resultsWithWeight.begin(), useBestNResults);
113 const auto& longestElement = *(std::max_element(m_resultsWithWeight.begin(), lastItemToUse,
114 TrackingUtilities::LessOf<NumberOfHitsGetter>()));
115 filteredResults.push_back(*(longestElement));
116 }
117 }
118 }
119
120
120}
The Module parameter list class.
TrackingUtilities::Findlet< typename AFilter::Object, typename AFilter::Object > Super
The parent class.
typename AFilter::Object Object
The object to filter.
std::vector< TrackingUtilities::WithWeight< Object * > > m_resultsWithWeight
temporary results vector with weights, out of which the overlaps will be build.
unsigned long m_param_useBestNInSeed
Parameter: In seed mode, use only the best seeds.
bool m_param_enableOverlapResolving
Parameter: Enable overlap.
AFilter m_filter
Subfindlet for filtering.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
OverlapResolver()
Construct this findlet and add the subfindlet as listener.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters of the subfindlet.
void apply(std::vector< Object > &results, std::vector< Object > &filteredResult) override
For each seed, search for the best candidate and return it.
Abstract base class for different kinds of events.
STL namespace.
Helper Functor to get the Seed of a given result.
Definition CKFFunctors.h:18
Type trait detecting whether a type provides a callable const getArrayIndex() member.