Belle II Software development
topology.test.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 <gtest/gtest.h>
9#include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
10
11#include <tracking/trackFindingCDC/eventdata/trajectories/CDCBFieldUtil.h>
12#include <tracking/trackFindingCDC/testFixtures/TrackFindingCDCTestWithTopology.h>
13#include <cdc/geometry/CDCGeometryPar.h>
14#include <framework/logging/Logger.h>
15
16using namespace Belle2;
17using namespace TrackFindingCDC;
18
20 public ::testing::WithParamInterface<int> {
21};
22
23TEST_P(SecondaryWireNeighborhoodTest, IsSymmetric)
24{
25 WireNeighborKind testNeighborKind(2, GetParam());
26 short oClockDirection = testNeighborKind.getOClockDirection();
27 short reverseOClockDirection = modulo(testNeighborKind.getOClockDirection() + 6, 12);
28
29 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
30
31 for (const CDCWire& wire : theWireTopology.getWires()) {
32 MayBePtr<const CDCWire> neighbor = wire.getSecondaryNeighbor(oClockDirection);
33 if (neighbor != nullptr) {
34 MayBePtr<const CDCWire> neighbor_of_neighbor =
35 neighbor->getSecondaryNeighbor(reverseOClockDirection);
36
37 EXPECT_EQ(*neighbor_of_neighbor, wire);
38
39 WireNeighborKind neighborKind = wire.getNeighborKind(*neighbor);
40 EXPECT_TRUE(neighborKind.isValid());
41 EXPECT_EQ(testNeighborKind.getCellDistance(), neighborKind.getCellDistance());
42 EXPECT_EQ(oClockDirection, neighborKind.getOClockDirection());
43 EXPECT_EQ(neighbor->getILayer() - wire.getILayer(), neighborKind.getILayerDifference());
44 }
45 }
46}
47
48INSTANTIATE_TEST_SUITE_P(SecondaryWireNeighborhoodTest_IsSymmetric,
50 ::testing::Range(0, 12));
51
52
53TEST_F(TrackFindingCDCTestWithTopology, topology_WireNeighborSymmetry_CWInwards)
54{
55
56 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
57
58 for (const CDCWire& wire : theWireTopology.getWires()) {
59 MayBePtr<const CDCWire> neighbor = wire.getNeighborCWInwards();
60 if (neighbor != nullptr) {
61 MayBePtr<const CDCWire> neighbor_of_neighbor = neighbor->getNeighborCCWOutwards();
62 EXPECT_EQ(*neighbor_of_neighbor, wire);
63
64 WireNeighborKind neighborKind = wire.getNeighborKind(*neighbor);
65 EXPECT_EQ(1, neighborKind.getCellDistance());
66 EXPECT_EQ(5, neighborKind.getOClockDirection());
67 EXPECT_EQ(-1, neighborKind.getILayerDifference());
68 }
69 }
70}
71
72TEST_F(TrackFindingCDCTestWithTopology, topology_WireNeighborSymmetry_CCWInwards)
73{
74
75 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
76
77 for (const CDCWire& wire : theWireTopology.getWires()) {
78 MayBePtr<const CDCWire> neighbor = wire.getNeighborCCWInwards();
79 if (neighbor != nullptr) {
80 MayBePtr<const CDCWire> neighbor_of_neighbor = neighbor->getNeighborCWOutwards();
81 EXPECT_EQ(*neighbor_of_neighbor, wire);
82
83 WireNeighborKind neighborKind = wire.getNeighborKind(*neighbor);
84 EXPECT_EQ(1, neighborKind.getCellDistance());
85 EXPECT_EQ(7, neighborKind.getOClockDirection());
86 EXPECT_EQ(-1, neighborKind.getILayerDifference());
87 }
88 }
89}
90
91TEST_F(TrackFindingCDCTestWithTopology, topology_WireNeighborSymmetry_CWOutwards)
92{
93
94 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
95
96 for (const CDCWire& wire : theWireTopology.getWires()) {
97 MayBePtr<const CDCWire> neighbor = wire.getNeighborCWOutwards();
98 if (neighbor != nullptr) {
99 MayBePtr<const CDCWire> neighbor_of_neighbor = neighbor->getNeighborCCWInwards();
100 EXPECT_EQ(*neighbor_of_neighbor, wire);
101
102 WireNeighborKind neighborKind = wire.getNeighborKind(*neighbor);
103 EXPECT_EQ(1, neighborKind.getCellDistance());
104 EXPECT_EQ(1, neighborKind.getOClockDirection());
105 EXPECT_EQ(1, neighborKind.getILayerDifference());
106 }
107 }
108}
109
110TEST_F(TrackFindingCDCTestWithTopology, topology_WireNeighborSymmetry_CCWOutwards)
111{
112
113 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
114
115 for (const CDCWire& wire : theWireTopology.getWires()) {
116 MayBePtr<const CDCWire> neighbor = wire.getNeighborCCWOutwards();
117 if (neighbor != nullptr) {
118 MayBePtr<const CDCWire> neighbor_of_neighbor = neighbor->getNeighborCWInwards();
119 EXPECT_EQ(*neighbor_of_neighbor, wire);
120
121 WireNeighborKind neighborKind = wire.getNeighborKind(*neighbor);
122 EXPECT_EQ(1, neighborKind.getCellDistance());
123 EXPECT_EQ(11, neighborKind.getOClockDirection());
124 EXPECT_EQ(1, neighborKind.getILayerDifference());
125 }
126 }
127}
128
129TEST_F(TrackFindingCDCTestWithTopology, topology_WireNeighborSymmetry_CCW)
130{
131
132 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
133
134 for (const CDCWire& wire : theWireTopology.getWires()) {
135 MayBePtr<const CDCWire> neighbor = wire.getNeighborCCW();
136 if (neighbor != nullptr) {
137 MayBePtr<const CDCWire> neighbor_of_neighbor = neighbor->getNeighborCW();
138 EXPECT_EQ(*neighbor_of_neighbor, wire);
139
140 WireNeighborKind neighborKind = wire.getNeighborKind(*neighbor);
141 EXPECT_EQ(1, neighborKind.getCellDistance());
142 EXPECT_EQ(9, neighborKind.getOClockDirection());
143 EXPECT_EQ(0, neighborKind.getILayerDifference());
144 }
145 }
146}
147
148TEST_F(TrackFindingCDCTestWithTopology, topology_WireNeighborSymmetry_CW)
149{
150
151 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
152
153 for (const CDCWire& wire : theWireTopology.getWires()) {
154 MayBePtr<const CDCWire> neighbor = wire.getNeighborCW();
155 if (neighbor != nullptr) {
156 MayBePtr<const CDCWire> neighbor_of_neighbor = neighbor->getNeighborCCW();
157 EXPECT_EQ(*neighbor_of_neighbor, wire);
158
159 WireNeighborKind neighborKind = wire.getNeighborKind(*neighbor);
160 EXPECT_EQ(1, neighborKind.getCellDistance());
161 EXPECT_EQ(3, neighborKind.getOClockDirection());
162 EXPECT_EQ(0, neighborKind.getILayerDifference());
163 }
164 }
165}
166
167TEST_F(TrackFindingCDCTestWithTopology, topology_CDCWire_stereoAngle)
168{
169 // Test if the all wires in the same superlayer have similar skew parameters.
170
171 double tanThetaByICLayer[CDCWireTopology::c_NLayers];
172 double stereoAngleByICLayer[CDCWireTopology::c_NLayers];
173 double refCylindricalRByICLayer[CDCWireTopology::c_NLayers];
174
175 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
176 for (const CDCWireLayer& wireLayer : theWireTopology.getWireLayers()) {
177 const ILayer iCLayer = wireLayer.getICLayer();
178
179 const CDCWire& firstWire = wireLayer.front();
180 tanThetaByICLayer[iCLayer] = firstWire.getTanStereoAngle();
181 stereoAngleByICLayer[iCLayer] = firstWire.getStereoAngle();
182 refCylindricalRByICLayer[iCLayer] = firstWire.getRefCylindricalR();
183
184 for (const CDCWire& wire : wireLayer) {
185 // this limits can change when a per-wire alignment is done using CDC dat
186 // therefore, this test might fail in the future, if new alignments for the CDC
187 // are created.
188 EXPECT_NEAR(tanThetaByICLayer[iCLayer], wire.getTanStereoAngle(), 10e-2);
189 EXPECT_NEAR(stereoAngleByICLayer[iCLayer], wire.getStereoAngle(), 10e-2);
190 EXPECT_NEAR(refCylindricalRByICLayer[iCLayer], wire.getRefCylindricalR(), 10e-2);
191 }
192
193 B2INFO("ICLayer : " << iCLayer);
194 B2INFO(" Tan Theta : " << tanThetaByICLayer[iCLayer]);
195 B2INFO(" Stereo angle : " << stereoAngleByICLayer[iCLayer]);
196 B2INFO(" Z range : " << wireLayer.getBackwardZ() << " to " << wireLayer.getForwardZ());
197 B2INFO(" Ref. cylindricalR : " << refCylindricalRByICLayer[iCLayer]);
198 B2INFO(" Max abs displacement : " << wireLayer.getWire(0).getWireVector().xy().norm());
199 }
200
201}
202
203
204
205TEST_F(TrackFindingCDCTestWithTopology, topology_RefCylindricalRVersusZInSuperLayers)
206{
207 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
208 for (const CDCWireSuperLayer& wireSuperLayer : theWireTopology.getWireSuperLayers()) {
209 if (wireSuperLayer.getStereoKind() == EStereoKind::c_Axial) {
210 EXPECT_EQ(0.0, wireSuperLayer.getRefTanLambda());
211 }
212
213 B2INFO("ISuperLayer : " << wireSuperLayer.getISuperLayer() <<
214 " Inner ref. z : " << wireSuperLayer.getInnerRefZ() <<
215 " Outer ref. z : " << wireSuperLayer.getOuterRefZ() <<
216 " CylindricalR Z slope : " << wireSuperLayer.getRefTanLambda()
217 );
218
219 }
220}
221
222TEST_F(TrackFindingCDCTestWithTopology, topology_ShowCurlCurv)
223{
224 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
225
226 double outerR = theWireTopology.getOuterCylindricalR();
227 double innerR = theWireTopology.getInnerCylindricalR();
228
229 double innerOriginCurv = 1 / (innerR / 2);
230 double outerOriginCurv = 1 / (outerR / 2);
231
232 double innerCurlCurv = 1 / innerR;
233 double outerCurlCurv = 1 / outerR;
234
235 B2INFO("Maximal curvature still reaching the CDC from IP : " << innerOriginCurv);
236 B2INFO("Minimal momentum still reaching the CDC from IP : " << CDCBFieldUtil::curvatureToAbsMom2D(innerOriginCurv, 1.5) << " GeV");
237
238 B2INFO("Maximal curvature still leaving the CDC from IP : " << outerOriginCurv);
239 B2INFO("Minimal momentum still leaving the CDC from IP : " << CDCBFieldUtil::curvatureToAbsMom2D(outerOriginCurv, 1.5) << " GeV");
240
241
242 B2INFO("Minimal curvature not reaching the CDC from VXD : " << innerCurlCurv);
243 B2INFO("Maximal momentum not reaching the CDC from VXD : " << CDCBFieldUtil::curvatureToAbsMom2D(innerCurlCurv, 1.5) << " GeV");
244
245 B2INFO("Minimal curvature not leaving the CDC from inside the CDC : " << outerCurlCurv);
246 B2INFO("Maximal momentum not leaving the CDC from inside the CDC : " << CDCBFieldUtil::curvatureToAbsMom2D(outerCurlCurv,
247 1.5) << " GeV");
248
249 for (const CDCWireSuperLayer& wireSuperLayer : theWireTopology.getWireSuperLayers()) {
250 double innerSLCurv = 1 / wireSuperLayer.getInnerCylindricalR();
251 B2INFO("Maximal curvature still reaching SL " << wireSuperLayer.getISuperLayer() << " from IP : " << innerSLCurv);
252 B2INFO("Minimal momentum still reaching SL " << wireSuperLayer.getISuperLayer() << " from IP : " <<
253 CDCBFieldUtil::curvatureToAbsMom2D(innerSLCurv, 1.5) << " GeV");
254 }
255}
256
257TEST_F(TrackFindingCDCTestWithTopology, topology_ShowLayerLimits)
258{
259 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
260 ISuperLayer iL = -1;
261 for (const CDCWireLayer& wireLayer : theWireTopology.getWireLayers()) {
262 ++iL;
263 B2INFO("Layer " << iL << ":");
264 B2INFO("z in " << wireLayer.getForwardZ() << ", " << wireLayer.getBackwardZ());
265 B2INFO("r in " << wireLayer.getInnerCylindricalR() << ", " << wireLayer.getOuterCylindricalR());
266 }
267}
268
269TEST_F(TrackFindingCDCTestWithTopology, topology_CDCGeometryPar_cellId)
270{
271 // Testing for a discrepancy in the cellId method of CDCGeometryPar
272 // Example in layer four
273 unsigned iCLayer = 4;
274
275 // Middle of the layer four
276 B2Vector3D posInMiddle(0, 0, 20.8);
277
278 unsigned iWireInFourthLayer = CDC::CDCGeometryPar::Instance().cellId(iCLayer, posInMiddle);
279 EXPECT_TRUE(iWireInFourthLayer < 160);
280 EXPECT_LT(iWireInFourthLayer, 160);
281}
282
283TEST_F(TrackFindingCDCTestWithTopology, topology_sag)
284{
285 const CDCWireTopology& theWireTopology = CDCWireTopology::getInstance();
286 for (const CDCWire& wire : theWireTopology.getWires()) {
287 const WireLine& wireLine = wire.getWireLine();
288 const double forwardZ = wireLine.forwardZ();
289 const double backwardZ = wireLine.backwardZ();
290 const double centerZ = (forwardZ + backwardZ) / 2;
291
292 EXPECT_LE(0, wireLine.sagCoeff());
293
294 EXPECT_EQ(wireLine.nominalPos2DAtZ(forwardZ).y(), wireLine.sagPos2DAtZ(forwardZ).y());
295 EXPECT_EQ(wireLine.nominalPos2DAtZ(backwardZ).y(), wireLine.sagPos2DAtZ(backwardZ).y());
296 EXPECT_GE(wireLine.nominalPos2DAtZ(centerZ).y(), wireLine.sagPos2DAtZ(centerZ).y());
297
298 EXPECT_LE(wireLine.nominalMovePerZ().y(), wireLine.sagMovePerZ(forwardZ).y());
299 EXPECT_GE(wireLine.nominalMovePerZ().y(), wireLine.sagMovePerZ(backwardZ).y());
300 EXPECT_EQ(wireLine.nominalMovePerZ().y(), wireLine.sagMovePerZ(centerZ).y());
301 }
302}
unsigned cellId(unsigned layerId, const B2Vector3D &position) const
The method to get cell id based on given layer id and the position.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
static double curvatureToAbsMom2D(double curvature, double bZ)
Conversion helper for two dimensional curvature to momenta.
Class representing a sense wire layer in the central drift chamber.
Definition: CDCWireLayer.h:42
Class representing a sense wire superlayer in the central drift chamber.
Class representing the sense wire arrangement in the whole of the central drift chamber.
static const ILayer c_NLayers
Total number of layers.
const std::vector< Belle2::TrackFindingCDC::CDCWireSuperLayer > & getWireSuperLayers() const
Getter for the underlying storing superlayer vector.
double getInnerCylindricalR() const
Getter for the inner radius of the inner most wire layer.
const std::vector< Belle2::TrackFindingCDC::CDCWire > & getWires() const
Getter for the underlying storing wire vector.
const std::vector< Belle2::TrackFindingCDC::CDCWireLayer > & getWireLayers() const
Getter for the underlying storing layer vector.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
double getOuterCylindricalR() const
Getter for the outer radius of the outer most wire layer.
Class representing a sense wire in the central drift chamber.
Definition: CDCWire.h:58
double getRefCylindricalR() const
Getter for the cylindrical radius at the wire reference position.
Definition: CDCWire.h:260
double getStereoAngle() const
Getter for the stereo angle of the wire.
Definition: CDCWire.h:244
double getTanStereoAngle() const
Getter for the tangents of the stereo angle of the wire.
Definition: CDCWire.h:240
This class provides the declaration of the common test fixture to all test of the track finding in th...
double y() const
Getter for the y coordinate.
Definition: Vector2D.h:605
A three dimensional limited line represented by its closest approach to the z-axes (reference positio...
Definition: WireLine.h:31
const Vector2D & nominalMovePerZ() const
Gives the positional move in the xy projection per unit z.
Definition: WireLine.h:71
Vector2D sagMovePerZ(const double z) const
Gives the two dimensional position with wire sag effect of the line at the given z value.
Definition: WireLine.h:75
double backwardZ() const
Gives the backward z coordinate.
Definition: WireLine.h:134
double forwardZ() const
Gives the forward z coordinate.
Definition: WireLine.h:130
double sagCoeff() const
Returns the wire sag coefficient due to gravity.
Definition: WireLine.h:231
Vector2D sagPos2DAtZ(const double z) const
Gives the two dimensional position with wire sag effect of the line at the given z value.
Definition: WireLine.h:60
Vector2D nominalPos2DAtZ(const double z) const
Gives the two dimensional position without wire sag effect of the line at the given z value.
Definition: WireLine.h:52
Type for the neighbor relationship from one wire to another.
bool isValid() const
Check if the neighbor kind is in principle valid.
short getOClockDirection() const
Get the direction on the clock to follow to reach the neighbor.
short getILayerDifference() const
Calculate the distance between the current and the layer of the designated neighbor.
short getCellDistance() const
Get the distance to the wire neighbor counted in number of cells.
Abstract base class for different kinds of events.