Belle II Software development
LayerPXDRelationFilter.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#include <tracking/ckf/pxd/filters/relations/LayerPXDRelationFilter.dcl.h>
9#include <tracking/trackFindingCDC/filters/base/RelationFilter.icc.h>
10
11#include <tracking/trackFindingCDC/utilities/StringManipulation.h>
12
13#include <tracking/spacePointCreation/SpacePoint.h>
14#include <framework/core/ModuleParamList.templateDetails.h>
15#include <vxd/geometry/GeoCache.h>
16
17namespace Belle2 {
23 template <class AFilter, class APrefilter>
25 {
28 }
29
30 template <class AFilter, class APrefilter>
32
33 template <class AFilter, class APrefilter>
35 {
36 // use value from DB if parameter is set to -1
37 moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "hitJumping"), m_param_hitJumping,
38 "Make it possible to jump over N layers.", m_param_hitJumping);
39
40 m_filter.exposeParameters(moduleParamList, prefix);
41 m_prefilter.exposeParameters(moduleParamList, TrackFindingCDC::prefixed("pre", prefix));
42
43 m_prefix = prefix;
44 }
45
46 template <class AFilter, class APrefilter>
48 {
49 Super::initialize();
50
51 if (m_prefix == "seed") {
52 m_ckfParameters = std::make_unique<OptionalDBObjPtr<CKFParameters>>("PXDCKFSeedHitParameters");
53 } else if (m_prefix == "hit") {
54 m_ckfParameters = std::make_unique<OptionalDBObjPtr<CKFParameters>>("PXDCKFHitHitParameters");
55 } else {
56 B2ERROR("Unknown prefix. Apparently, some non-trivial changes to code were done.");
57 }
58 }
59
60 template <class AFilter, class APrefilter>
62 {
63 Super::beginRun();
64
65 // use values from payload if parameter is set to -1
66 if (m_param_hitJumping == -1) {
67 if (m_ckfParameters->isValid()) {
68 m_layerJumpPtThreshold = (*m_ckfParameters)->getLayerJumpPtThreshold();
69 m_layerJumpLowPt = (*m_ckfParameters)->getLayerJumpLowPt();
70 m_layerJumpHighPt = (*m_ckfParameters)->getLayerJumpHighPt();
71 if (m_prefix == "hit" && m_layerJumpPtThreshold > 0.) {
72 // if we want to have this, some major restructure of the whole CKF code is necessary
73 // (CKF states from hits don't know anything about the seed track, i.e. you cannot access its momentum)
74 B2FATAL("pt dependence of layerJump parameter currently not implemented for hit->hit extrapolation.");
75 }
76 } else {
77 B2FATAL("Trying to read layerJump parameter from DB but payload '" << m_ckfParameters->getName() << "' not found.");
78 }
79 // we don't need all this if simple value from python config is to be used
80 } else {
81 m_layerJumpPtThreshold = -1;
82 m_layerJumpLowPt = m_param_hitJumping;
83 m_layerJumpHighPt = m_param_hitJumping;
84 }
85 }
86
87 template <class AFilter, class APrefilter>
88 std::vector<CKFToPXDState*>
90 const std::vector<CKFToPXDState*>& states) const
91 {
92 std::vector<CKFToPXDState*> possibleNextStates;
93
94 const CKFToPXDState::stateCache& currentStateCache = currentState->getStateCache();
95 const unsigned int& currentLayer = currentStateCache.geoLayer;
96
97 // this is the parameter value set in the python config
98 int m_hitJump = m_param_hitJumping;
99 // if it is set to -1 we want to use the values in the payload
100 if (m_hitJump == -1) {
101 m_hitJump = currentStateCache.ptSeed < m_layerJumpPtThreshold ? m_layerJumpLowPt : m_layerJumpHighPt;
102 }
103
104 const unsigned int& nextPossibleLayer = std::max(static_cast<int>(currentLayer) - 1 - m_hitJump, 0);
105
106 // Patch for the PXD layer 2 overlap inefficiency fix
107 // previous implementation of maximumLadderNumber was calculated using GeoCache gave incorrect value for exp1003
108 // Geometrically, PXD layer 1 has 8 ladders, pxd layer 2 has 12 ladder
109 int numberOfLaddersForLayer[2] = {8, 12};
110
111 for (CKFToPXDState* nextState : states) {
112 const CKFToPXDState::stateCache& nextStateCache = nextState->getStateCache();
113 const unsigned int nextLayer = nextStateCache.geoLayer;
114 if (nextLayer < std::min(currentLayer, nextPossibleLayer) or std::max(currentLayer, nextPossibleLayer) < nextLayer) {
115 continue;
116 }
117
118 if (currentLayer == nextLayer) {
119 // next layer is an overlap one, so lets return all hits from the same layer, that are on a
120 // ladder which is below the last added hit.
121 const unsigned int fromLadderNumber = currentStateCache.ladder;
122 const unsigned int maximumLadderNumber = numberOfLaddersForLayer[currentLayer - 1];
123
124 // the reason for this strange formula is the numbering scheme in the VXD.
125 // we first substract 1 from the ladder number to have a ladder counting from 0 to N - 1,
126 // then we add (PXD)/subtract(PXD) one to get to the next (overlapping) ladder and do a % N to also cope for the
127 // highest number. Then we add 1 again, to go from the counting from 0 .. N-1 to 1 .. N.
128 // The + maximumLadderNumber in between makes sure, we are not ending with negative numbers
129 const int direction = 1;
130 const unsigned int overlappingLadder =
131 ((fromLadderNumber + maximumLadderNumber - 1) + direction) % maximumLadderNumber + 1;
132
133 if (nextStateCache.ladder != overlappingLadder) {
134 continue;
135 }
136
137 // Next we make sure to not have any cycles in our graph: we do this by defining only the halves of the
138 // sensor as overlapping. So if the first hit is coming from sensor 1 and the second from sensor 2,
139 // they are only related if the one from sensor 1 is on the half, that is pointing towards sensor 2
140 // and the one on sensor 2 is on the half that is pointing towards sensor 1.
141 //
142 // X X X
143 // ----|---- ----|---- ----|----
144 // This is fine: X This not: X This not: X
145 // ----|---- ----|---- ----|----
146
147 // for PXD its the other way round!
148 if (currentStateCache.localNormalizedu <= 0.8f) {
149 continue;
150 }
151
152 if (nextStateCache.localNormalizedu > 0.2f) {
153 continue;
154 }
155 }
156
157 // Some loose prefiltering of possible states
158 TrackFindingCDC::Weight weight = m_prefilter(std::make_pair(currentState, nextState));
159 if (std::isnan(weight)) {
160 continue;
161 }
162
163 possibleNextStates.push_back(nextState);
164 }
165
166 return possibleNextStates;
167 }
168
169 template <class AFilter, class APrefilter>
171 {
172 return m_filter(std::make_pair(&from, &to));
173 }
175}
Specialized CKF State for extrapolating into the PXD.
Definition: CKFToPXDState.h:27
const struct stateCache & getStateCache() const
Get the cached data of this state.
Definition: CKFToPXDState.h:48
APrefilter m_prefilter
Loose pre-filter to reject possibleTos.
AFilter m_filter
Filter for rejecting the states.
The Module parameter list class.
void addProcessingSignalListener(ProcessingSignalListener *psl)
Register a processing signal listener to be notified.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
TrackFindingCDC::Weight operator()(const CKFToPXDState &from, const CKFToPXDState &to) override
Give a final weight to the possibilities by asking the filter.
void initialize() override
Receive signal before the start of the event processing.
LayerPXDRelationFilter()
Add the filter as listener.
void beginRun() override
Receive signal for the beginning of a new run.
std::vector< CKFToPXDState * > getPossibleTos(CKFToPXDState *from, const std::vector< CKFToPXDState * > &states) const override
Return all states the given state is possible related to.
~LayerPXDRelationFilter()
Default destructor.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) override
Expose the parameters of the filter.
Abstract base class for different kinds of events.