Belle II Software  release-08-01-10
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 
15 using namespace Belle2;
16 using namespace TrackFindingCDC;
17 
19 {
20 }
21 
22 void 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 
35 void 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 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
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...
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.
Interface for a minimal algorithm part that wants to expose some parameters to a module.
Definition: Findlet.h:26
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.