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/trackFindingCDC/eventdata/segments/CDCWireHitCluster.h>
11#include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
12
13#include <tracking/trackFindingCDC/topology/CDCWireLayer.h>
14#include <tracking/trackFindingCDC/topology/CDCWire.h>
15
16#include <tracking/trackFindingCDC/filters/base/RelationFilterUtil.h>
17
18#include <tracking/trackFindingCDC/utilities/Functional.h>
19#include <tracking/trackFindingCDC/utilities/Algorithms.h>
20#include <tracking/trackFindingCDC/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 TrackFindingCDC;
29
31{
33}
34
36{
37 return "Groups the wire hits into super cluster by expanding the secondary wire "
38 "neighborhood";
39}
40
41void SuperClusterCreator::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
42{
43 moduleParamList->addParameter(prefixed(prefix, "expandOverApogeeGap"),
45 "Expand the super clusters over the typical gap at the apogee of the trajectory",
47
48 m_wireHitRelationFilter.exposeParameters(moduleParamList, prefix);
49}
50
51void SuperClusterCreator::apply(std::vector<CDCWireHit>& inputWireHits,
52 std::vector<CDCWireHitCluster>& outputSuperClusters)
53{
54 m_wireHitRelations.clear();
55
57 auto wireHitsByLayer =
58 adjacent_groupby(inputWireHits.begin(), inputWireHits.end(), [](const CDCWireHit & wireHit) {
59 return wireHit.getWireID().getILayer();
60 });
61
62 for (const auto& wireHitsInLayer : wireHitsByLayer) {
63 const CDCWireLayer& wireLayer = wireHitsInLayer.front().getWire().getWireLayer();
64 const int nWires = wireLayer.size();
65
66 auto sameWireHitChain = [](const CDCWireHit & lhs, const CDCWireHit & rhs) {
67 return rhs.getWireID().getIWire() - lhs.getWireID().getIWire() == 1;
68 };
69
70 auto wireHitChains =
71 unique_ranges(wireHitsInLayer.begin(), wireHitsInLayer.end(), sameWireHitChain);
72
73 size_t nWireHits = 0;
74 for (const VectorRange<CDCWireHit>& wireHitChain : wireHitChains) {
75 nWireHits += wireHitChain.size();
76 }
77 assert(nWireHits == wireHitsInLayer.size());
78
79 // Special treatment for the first and last wireHitChain as they might wrap around as one
80 VectorRange<CDCWireHit> frontWrapChain(wireHitsInLayer.begin(), wireHitsInLayer.begin());
81 VectorRange<CDCWireHit> backWrapChain(wireHitsInLayer.end(), wireHitsInLayer.end());
82 if (wireHitChains.size() > 1) {
83 if (wireHitChains.front().front().getWire().isPrimaryNeighborWith(
84 wireHitChains.back().back().getWire())) {
85 // Chains are touching
86 // Keep their information around but eliminate them from the regular chains
87 int wrapAroundChainSize = wireHitChains.front().size() + wireHitChains.back().size();
88 if (wrapAroundChainSize >= 5) {
89 // Warning reach over the local wire hit layer / outside the memory of the wire hit
90 // vector to transport the size.
91 frontWrapChain = wireHitChains.front();
92 frontWrapChain.first = frontWrapChain.end() - wrapAroundChainSize;
93
94 backWrapChain = wireHitChains.back();
95 backWrapChain.second = backWrapChain.begin() + wrapAroundChainSize;
96
97 wireHitChains.erase(wireHitChains.begin());
98 wireHitChains.pop_back();
99 }
100 }
101 }
102
103 auto itLastChain = std::remove_if(wireHitChains.begin(), wireHitChains.end(), Size() < 5u);
104 wireHitChains.erase(itLastChain, wireHitChains.end());
105 if (wireHitChains.empty()) continue;
106
107 auto connectWireHitChains = [this, nWires](const VectorRange<CDCWireHit>& lhs,
108 const VectorRange<CDCWireHit>& rhs) {
109 int iWireDelta = rhs.front().getWireID().getIWire() - lhs.back().getWireID().getIWire();
110 if (iWireDelta < 0) iWireDelta += nWires;
111 if (iWireDelta < static_cast<int>(lhs.size() + rhs.size())) {
112 m_wireHitRelations.push_back({&rhs.front(), 0, &lhs.back()});
113 m_wireHitRelations.push_back({&lhs.back(), 0, &rhs.front()});
114 }
115 return false;
116 };
117 // the return value is not needed
118 std::ignore = std::adjacent_find(wireHitChains.begin(), wireHitChains.end(), connectWireHitChains);
119
120 if (not frontWrapChain.empty()) {
121 connectWireHitChains(frontWrapChain, wireHitChains.front());
122 }
123 if (not backWrapChain.empty()) {
124 connectWireHitChains(wireHitChains.back(), backWrapChain);
125 }
126 if (backWrapChain.empty() and frontWrapChain.empty()) {
127 connectWireHitChains(wireHitChains.back(), wireHitChains.front());
128 }
129 }
130 }
131
133 const std::vector<CDCWireHit*> wireHitPtrs = as_pointers<CDCWireHit>(inputWireHits);
134
137
138 B2ASSERT("Expect wire hit neighborhood to be symmetric ",
140
141 m_wirehitClusterizer.apply(wireHitPtrs, m_wireHitRelations, outputSuperClusters);
142
143 int iSuperCluster = -1;
144 for (CDCWireHitCluster& superCluster : outputSuperClusters) {
145 ++iSuperCluster;
146 superCluster.setISuperCluster(iSuperCluster);
147 for (CDCWireHit* wireHit : superCluster) {
148 wireHit->setISuperCluster(iSuperCluster);
149 }
150 std::sort(superCluster.begin(), superCluster.end());
151 }
152}
The Module parameter list class.
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:55
const WireID & getWireID() const
Getter for the WireID of the wire the hit is located on.
Definition: CDCWireHit.h:185
Class representating a sense wire layer in the central drift chamber.
Definition: CDCWireLayer.h:42
void addProcessingSignalListener(ProcessingSignalListener *psl)
Register a processing signal listener to be notified.
A pair of iterators usable with the range base for loop.
Definition: Range.h:25
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 derefenced iterator before end()
Definition: Range.h:84
Reference front() const
Returns the derefenced 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
void apply(std::vector< CDCWireHit > &inputWireHits, std::vector< CDCWireHitCluster > &outputSuperClusters) final
Main algorithm applying the cluster refinement.
bool m_param_expandOverApogeeGap
Parameter : Expand the super clusters over the typical gap at the apogee of the trajectory.
std::vector< WeightedRelation< CDCWireHit > > m_wireHitRelations
Memory for the wire hit neighborhood in a cluster.
std::string getDescription() final
Short description of the findlet.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
Clusterizer< CDCWireHit, CDCWireHitCluster > m_wirehitClusterizer
Instance of the hit cluster generator.
WholeWireHitRelationFilter m_wireHitRelationFilter
Wire hit neighborhood relation filter.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
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 abitrary objects.
Definition: Functional.h:318
Utility structure with functions related to weighted relations.