Belle II Software development
SuperClusterCreator.cc
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#include <tracking/trackFindingCDC/findlets/minimal/SuperClusterCreator.h>
9
10#include <tracking/trackingUtilities/eventdata/segments/CDCWireHitCluster.h>
11#include <tracking/trackingUtilities/eventdata/hits/CDCWireHit.h>
12
13#include <cdc/topology/CDCWireLayer.h>
14#include <cdc/topology/CDCWire.h>
15
16#include <tracking/trackingUtilities/filters/base/RelationFilterUtil.h>
17
18#include <tracking/trackingUtilities/utilities/Functional.h>
19#include <tracking/trackingUtilities/utilities/Algorithms.h>
20#include <tracking/trackingUtilities/utilities/StringManipulation.h>
21
22#include <framework/core/ModuleParamList.templateDetails.h>
23
24// for std::ignore
25#include <utility>
26
27using namespace Belle2;
28using namespace CDC;
29using namespace TrackFindingCDC;
30using namespace TrackingUtilities;
31
36
38{
39 return "Groups the wire hits into super cluster by expanding the secondary wire "
40 "neighborhood";
41}
42
43void SuperClusterCreator::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
44{
45 moduleParamList->addParameter(prefixed(prefix, "expandOverApogeeGap"),
47 "Expand the super clusters over the typical gap at the apogee of the trajectory",
49
50 m_wireHitRelationFilter.exposeParameters(moduleParamList, prefix);
51}
52
53void SuperClusterCreator::apply(std::vector<CDCWireHit>& inputWireHits,
54 std::vector<CDCWireHitCluster>& outputSuperClusters)
55{
56 m_wireHitRelations.clear();
57
59 auto wireHitsByLayer =
60 adjacent_groupby(inputWireHits.begin(), inputWireHits.end(), [](const CDCWireHit & wireHit) {
61 return wireHit.getWireID().getILayer();
62 });
63
64 for (const auto& wireHitsInLayer : wireHitsByLayer) {
65 const CDCWireLayer& wireLayer = wireHitsInLayer.front().getWire().getWireLayer();
66 const int nWires = wireLayer.size();
67
68 auto sameWireHitChain = [](const CDCWireHit & lhs, const CDCWireHit & rhs) {
69 return rhs.getWireID().getIWire() - lhs.getWireID().getIWire() == 1;
70 };
71
72 auto wireHitChains =
73 unique_ranges(wireHitsInLayer.begin(), wireHitsInLayer.end(), sameWireHitChain);
74
75 size_t nWireHits = 0;
76 for (const VectorRange<CDCWireHit>& wireHitChain : wireHitChains) {
77 nWireHits += wireHitChain.size();
78 }
79 assert(nWireHits == wireHitsInLayer.size());
80
81 // Special treatment for the first and last wireHitChain as they might wrap around as one
82 VectorRange<CDCWireHit> frontWrapChain(wireHitsInLayer.begin(), wireHitsInLayer.begin());
83 VectorRange<CDCWireHit> backWrapChain(wireHitsInLayer.end(), wireHitsInLayer.end());
84 if (wireHitChains.size() > 1) {
85 if (wireHitChains.front().front().getWire().isPrimaryNeighborWith(
86 wireHitChains.back().back().getWire())) {
87 // Chains are touching
88 // Keep their information around but eliminate them from the regular chains
89 int wrapAroundChainSize = wireHitChains.front().size() + wireHitChains.back().size();
90 if (wrapAroundChainSize >= 5) {
91 // Warning reach over the local wire hit layer / outside the memory of the wire hit
92 // vector to transport the size.
93 frontWrapChain = wireHitChains.front();
94 frontWrapChain.first = frontWrapChain.end() - wrapAroundChainSize;
95
96 backWrapChain = wireHitChains.back();
97 backWrapChain.second = backWrapChain.begin() + wrapAroundChainSize;
98
99 wireHitChains.erase(wireHitChains.begin());
100 wireHitChains.pop_back();
101 }
102 }
103 }
104
105 auto itLastChain = std::remove_if(wireHitChains.begin(), wireHitChains.end(), Size() < 5u);
106 wireHitChains.erase(itLastChain, wireHitChains.end());
107 if (wireHitChains.empty()) continue;
108
109 auto connectWireHitChains = [this, nWires](const VectorRange<CDCWireHit>& lhs,
110 const VectorRange<CDCWireHit>& rhs) {
111 int iWireDelta = rhs.front().getWireID().getIWire() - lhs.back().getWireID().getIWire();
112 if (iWireDelta < 0) iWireDelta += nWires;
113 if (iWireDelta < static_cast<int>(lhs.size() + rhs.size())) {
114 m_wireHitRelations.push_back({&rhs.front(), 0, &lhs.back()});
115 m_wireHitRelations.push_back({&lhs.back(), 0, &rhs.front()});
116 }
117 return false;
118 };
119 // the return value is not needed
120 std::ignore = std::adjacent_find(wireHitChains.begin(), wireHitChains.end(), connectWireHitChains);
121
122 if (not frontWrapChain.empty()) {
123 connectWireHitChains(frontWrapChain, wireHitChains.front());
124 }
125 if (not backWrapChain.empty()) {
126 connectWireHitChains(wireHitChains.back(), backWrapChain);
127 }
128 if (backWrapChain.empty() and frontWrapChain.empty()) {
129 connectWireHitChains(wireHitChains.back(), wireHitChains.front());
130 }
131 }
132 }
133
135 const std::vector<CDCWireHit*> wireHitPtrs = as_pointers<CDCWireHit>(inputWireHits);
136
139
140 B2ASSERT("Expect wire hit neighborhood to be symmetric ",
142
143 m_wirehitClusterizer.apply(wireHitPtrs, m_wireHitRelations, outputSuperClusters);
144
145 int iSuperCluster = -1;
146 for (CDCWireHitCluster& superCluster : outputSuperClusters) {
147 ++iSuperCluster;
148 superCluster.setISuperCluster(iSuperCluster);
149 for (CDCWireHit* wireHit : superCluster) {
150 wireHit->setISuperCluster(iSuperCluster);
151 }
152 std::sort(superCluster.begin(), superCluster.end());
153 }
154}
Class representing a sense wire layer in the central drift chamber.
The Module parameter list class.
void apply(std::vector< TrackingUtilities::CDCWireHit > &inputWireHits, std::vector< TrackingUtilities::CDCWireHitCluster > &outputSuperClusters) final
Main algorithm applying the cluster refinement.
TrackingUtilities::Clusterizer< TrackingUtilities::CDCWireHit, TrackingUtilities::CDCWireHitCluster > m_wirehitClusterizer
Instance of the hit cluster generator.
bool m_param_expandOverApogeeGap
Parameter : Expand the super clusters over the typical gap at the apogee of the trajectory.
std::string getDescription() final
Short description of the findlet.
std::vector< TrackingUtilities::WeightedRelation< TrackingUtilities::CDCWireHit > > m_wireHitRelations
Memory for the wire hit neighborhood in a cluster.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
WholeWireHitRelationFilter m_wireHitRelationFilter
Wire hit neighborhood relation filter.
Class representing a hit wire in the central drift chamber.
Definition CDCWireHit.h:58
const WireID & getWireID() const
Getter for the WireID of the wire the hit is located on.
Definition CDCWireHit.h:188
Iterator begin() const
Begin of the range for range based for.
Definition Range.h:64
Iterator end() const
End of the range for range based for.
Definition Range.h:68
bool empty() const
Checks if the begin equals the end iterator, hence if the range is empty.
Definition Range.h:72
Reference back() const
Returns the dereferenced iterator before end()
Definition Range.h:84
Reference front() const
Returns the dereferenced iterator at begin()
Definition Range.h:80
std::size_t size() const
Returns the total number of objects in this range.
Definition Range.h:76
unsigned short getIWire() const
Getter for wire within the layer.
Definition WireID.h:145
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
Abstract base class for different kinds of events.
static void appendUsing(ARelationFilter &relationFilter, const std::vector< AObject * > &froms, const std::vector< AObject * > &tos, std::vector< WeightedRelation< AObject > > &weightedRelations, unsigned int maximumNumberOfRelations=std::numeric_limits< unsigned int >::max())
Appends relations between elements in the given AItems using the ARelationFilter.
Functor to get the .size() from an arbitrary objects.
Definition Functional.h:318
static bool areSymmetric(const AWeightedRelations &weightedRelations)
Checks for the symmetry of a range of weighted relations Explicitly checks for each weighted relation...