Belle II Software development
DATCONSVDClusterLoaderAndPreparer.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/datcon/findlets/DATCONSVDClusterLoaderAndPreparer.h>
9#include <tracking/datcon/utilities/DATCONHelpers.h>
10#include <tracking/trackFindingCDC/utilities/StringManipulation.h>
11#include <svd/dataobjects/SVDCluster.h>
12#include <vxd/dataobjects/VxdID.h>
13#include <framework/core/ModuleParamList.h>
14
15using namespace Belle2;
16using namespace TrackFindingCDC;
17
19{
20}
21
22void DATCONSVDClusterLoaderAndPreparer::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
23{
24 Super::exposeParameters(moduleParamList, prefix);
25
26 moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maxClustersPerLayer"), m_param_maxClustersPerLayer,
27 "Maximum number of clusters on one layer before aborting tracking.", m_param_maxClustersPerLayer);
28}
29
31{
33}
34
35void DATCONSVDClusterLoaderAndPreparer::apply(const std::vector<SVDCluster>& uClusters, const std::vector<SVDCluster>& vClusters,
36 std::vector<std::pair<VxdID, std::pair<long, long>>>& uHits,
37 std::vector<std::pair<VxdID, std::pair<long, long>>>& vHits)
38{
39 if (uClusters.size() == 0 or vClusters.size() == 0) {
40 return;
41 }
42
43 m_nClusterPerLayer.fill(0);
44
45 for (auto& cluster : uClusters) {
46 const VxdID& sensorID = cluster.getSensorID();
47 const uint& layerNumber = sensorID.getLayerNumber();
48 const uint& ladderNumber = sensorID.getLadderNumber();
49 const long localPosition = convertFloatToInt(cluster.getPosition(), 4); // convert the cluster position from cm to µm
50
51 m_nClusterPerLayer.at(layerNumber - 3)++;
52 const double rotangle = m_const_InitialAngle[layerNumber - 3] + (ladderNumber - 1) * m_const_AngleStep[layerNumber - 3];
53 const double cosRotAngle = cos(rotangle);
54 const double sinRotAngle = sin(rotangle);
55 const int sensorRadius = m_const_SVDRadii[layerNumber - 3];
56 const int ytmp = localPosition + m_const_RPhiShiftsOfLayers[layerNumber - 3];
57
58 // perform 2D rotation
59 const long x = round(sensorRadius * cosRotAngle - ytmp * sinRotAngle); // x is in µm
60 const long y = round(sensorRadius * sinRotAngle + ytmp * cosRotAngle); // y is in µm
61 const long radiusSquared = x * x + y * y; // therefore radius is in µm as well, like all other length values
62 // x or y divided by r^2 can create values very close to 0. To cope for this and still
63 // have non-zero numbers after conversion and rounding, the conversion to int is made with 10^10
64 std::pair<long, long> pos2D = std::make_pair(convertFloatToInt(2. * (double)x / (double)radiusSquared, 10),
65 convertFloatToInt(2. * (double)y / (double)radiusSquared, 10));
66 B2DEBUG(29, "x, y: " << x << " " << y << " Hough-values: " << pos2D.first << " " << pos2D.second);
67 uHits.emplace_back(std::make_pair(sensorID, pos2D));
68 }
69
70 /* First convert to absolute hits and save into a map */
71 for (auto& cluster : vClusters) {
72 const VxdID& sensorID = cluster.getSensorID();
73 const uint& layerNumber = sensorID.getLayerNumber();
74 const uint& sensorNumber = sensorID.getSensorNumber();
75 const long localPosition = convertFloatToInt(cluster.getPosition(), 4); // convert the cluster position from cm to µm
76
77 m_nClusterPerLayer.at(4 + layerNumber - 3)++;
78 const int radius = m_const_SVDRadii[layerNumber - 3];
79 int z = 0;
80 if (layerNumber == 3) {
81 z = localPosition + m_const_ZShiftL3[sensorNumber - 1];
82 } else {
83 switch (layerNumber) {
84 case 4:
85 if (sensorNumber == 1) {
86 z = localPosition * m_const_CosSlantedAngles[layerNumber - 3] + m_const_ZShiftL4[sensorNumber - 1];
87 } else {
88 z = localPosition + m_const_ZShiftL4[sensorNumber - 1];
89 }
90 break;
91 case 5:
92 if (sensorNumber == 1) {
93 z = localPosition * m_const_CosSlantedAngles[layerNumber - 3] + m_const_ZShiftL5[sensorNumber - 1];
94 } else {
95 z = localPosition + m_const_ZShiftL5[sensorNumber - 1];
96 }
97 break;
98 case 6:
99 if (sensorNumber == 1) {
100 z = localPosition * m_const_CosSlantedAngles[layerNumber - 3] + m_const_ZShiftL6[sensorNumber - 1];
101 } else {
102 z = localPosition + m_const_ZShiftL6[sensorNumber - 1];
103 }
104 break;
105 }
106 }
107 vHits.emplace_back(std::make_pair(sensorID, std::make_pair(z, radius)));
108 }
109
110 const uint* maxOfClustersPerLayer = std::max_element(m_nClusterPerLayer.begin(), m_nClusterPerLayer.end());
111 if (*maxOfClustersPerLayer > m_param_maxClustersPerLayer) {
112 B2WARNING("High occupancy in SVD, aborting FPGA-DATCON...");
113 uHits.clear();
114 vHits.clear();
115 }
116
117}
const std::array< int, 3 > m_const_ZShiftL4
shift along z of the L4 senosrs, in µn
uint m_param_maxClustersPerLayer
Cut value for aborting tracking if more than this number of clusters is found on one layer.
void apply(const std::vector< SVDCluster > &uClusters, const std::vector< SVDCluster > &vClusters, std::vector< std::pair< VxdID, std::pair< long, long > > > &uHits, std::vector< std::pair< VxdID, std::pair< long, long > > > &vHits) override
Load the SVDClusters and create two vectors containing the hits prepared for intercept finding This f...
void initialize() override
Create the store arrays.
std::array< uint, 8 > m_nClusterPerLayer
array containing the number of clusters per layer. If this exceeds a cut value, tracking is aborted
const std::array< int, 2 > m_const_ZShiftL3
shift along z of the L3 senosrs, in µn
const std::array< double, 4 > m_const_AngleStep
angle difference between two consecutive ladders, in rad
const std::array< int, 4 > m_const_RPhiShiftsOfLayers
shift in r-phi to create windmill structure, in µm
const std::array< double, 4 > m_const_InitialAngle
phi-value of the first ladder in each layer, i.e. sensors X.1.Y, in rad
const std::array< double, 4 > m_const_CosSlantedAngles
cosine values of the slanted sensors
DATCONSVDClusterLoaderAndPreparer()
Load clusters and prepare them for intercept finding.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) override
Expose the parameters of the sub findlets.
const std::array< int, 4 > m_const_ZShiftL5
shift along z of the L5 senosrs, in µn
const std::array< int, 5 > m_const_ZShiftL6
shift along z of the L6 senosrs, in µn
const std::array< int, 4 > m_const_SVDRadii
Radii of the SVD layers, in µm.
The Module parameter list class.
void initialize() override
Receive and dispatch signal before the start of the event processing.
virtual void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix)
Forward prefixed parameters of this findlet to the module parameter list.
Definition: Findlet.h:69
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getSensorNumber() const
Get the sensor id.
Definition: VxdID.h:100
baseType getLadderNumber() const
Get the ladder id.
Definition: VxdID.h:98
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
long convertFloatToInt(double value, int power)
Convert float or double to long int for more similarity to the FPGA implementation.
Definition: DATCONHelpers.h:21
Abstract base class for different kinds of events.