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
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
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...
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
TrackFindingCDC::Findlet< const SVDCluster, const SVDCluster, std::pair< VxdID, std::pair< long, long > >, std::pair< VxdID, std::pair< long, long > > > Super
Parent class.
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.
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.
Abstract base class for different kinds of events.