Belle II Software  release-06-02-00
ROIFinder.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/vxdHoughTracking/findlets/ROIFinder.h>
9 #include <tracking/vxdHoughTracking/findlets/RawTrackCandCleaner.icc.h>
10 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
11 #include <framework/logging/Logger.h>
12 #include <framework/core/ModuleParamList.h>
13 #include <framework/geometry/BFieldManager.h>
14 #include <framework/geometry/B2Vector3.h>
15 #include <framework/database/DBObjPtr.h>
16 #include <mdst/dbobjects/BeamSpot.h>
17 #include <pxd/geometry/SensorInfo.h>
18 #include <vxd/geometry/GeoCache.h>
19 
20 using namespace Belle2;
21 using namespace TrackFindingCDC;
22 using namespace vxdHoughTracking;
23 
24 ROIFinder::~ROIFinder() = default;
25 
26 ROIFinder::ROIFinder()
27 {
28 }
29 
30 void ROIFinder::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
31 {
32  Super::exposeParameters(moduleParamList, prefix);
33 
34  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "calculateROI"), m_param_calculateROI,
35  "Calculate PXDIntercepts and ROIs in this findlet based on a simple circle extrapolation (r-phi) and straigh line extrapolation (z, theta)?",
36  m_param_calculateROI);
37 
38  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "storePXDInterceptsName"), m_param_storePXDInterceptsName,
39  "Name of the PXDIntercepts StoreArray produced by DATCON using a simple circle extrapolation in r-phi and a straight line extrapolation in theta.",
40  m_param_storePXDInterceptsName);
41 
42  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "storeROIsName"), m_param_storeROIsName,
43  "Name of the ROIs StoreArray produced by DATCON using a simple circle extrapolation in r-phi and a straight line extrapolation in theta.",
44  m_param_storeROIsName);
45 
46  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "tolerancePhi"), m_param_tolerancePhi,
47  "Allowed tolerance in phi (in radians) (for ROI calculation in u direction). If the intercept is within this range of the active region, an intercept is created.",
48  m_param_tolerancePhi);
49  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "toleranceZ"), m_param_toleranceZ,
50  "Allowed tolerance in z (in cm) (for ROI calculation in v direction). If the intercept is within this range of the active region of a sensor, an intercept is created.",
51  m_param_toleranceZ);
52 
53  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "radiusCorrectionFactor"), m_param_radiusCorrectionFactor,
54  "Correct charge-dependent bias of the extrapolated hit with radiusCorrectionFactor * trackCharge / trackRadius.",
55  m_param_radiusCorrectionFactor);
56  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "sinPhiCorrectionFactor"), m_param_sinPhiCorrectionFactor,
57  "Correct sin(trackPhi) dependent bias with sinPhiCorrectionFactor * sin(trackPhi).",
58  m_param_sinPhiCorrectionFactor);
59  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "cosPhiCorrectionFactor"), m_param_cosPhiCorrectionFactor,
60  "Correct cos(trackPhi) dependent bias with cosPhiCorrectionFactor * cos(trackPhi).",
61  m_param_cosPhiCorrectionFactor);
62 
63  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimumROISizeUL1"), m_param_minimumROISizeUL1,
64  "Minimum ROI size (in pixel) in u direction on L1.", m_param_minimumROISizeUL1);
65  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimumROISizeVL1"), m_param_minimumROISizeVL1,
66  "Minimum ROI size (in pixel) in v direction on L1.", m_param_minimumROISizeVL1);
67  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimumROISizeUL2"), m_param_minimumROISizeUL2,
68  "Minimum ROI size (in pixel) in u direction on L2.", m_param_minimumROISizeUL2);
69  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimumROISizeVL2"), m_param_minimumROISizeVL2,
70  "Minimum ROI size (in pixel) in v direction on L2.", m_param_minimumROISizeVL2);
71 
72  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "multiplierUL1"), m_param_multiplierUL1,
73  "Multiplier term for ROI size estimation for L1 u direction. Usage: multiplierUL1 * 1/R + minimumROISizeUL1, with R in cm.",
74  m_param_multiplierUL1);
75  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "multiplierUL2"), m_param_multiplierUL2,
76  "Multiplier term for ROI size estimation for L2 u direction. Usage: multiplierUL2 * 1/R + minimumROISizeUL2, with R in cm.",
77  m_param_multiplierUL2);
78  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "multiplierVL1"), m_param_multiplierVL1,
79  "Multiplier term for ROI size estimation for L1 v direction. Usage: (1 + abs(tan(lambda)) * multiplierVL1) + minimumROISizeVL1.",
80  m_param_multiplierVL1);
81  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "multiplierVL2"), m_param_multiplierVL2,
82  "Multiplier term for ROI size estimation for L2 v direction. Usage: (1 + abs(tan(lambda)) * multiplierVL2) + minimumROISizeVL2.",
83  m_param_multiplierVL2);
84 
85  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maximumROISizeU"), m_param_maximumROISizeU,
86  "Maximum ROI size in u.", m_param_maximumROISizeU);
87  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "maximumROISizeV"), m_param_maximumROISizeV,
88  "Maximum ROI size in v.", m_param_maximumROISizeV);
89 
90 }
91 
93 void ROIFinder::initialize()
94 {
95  // If no ROIs shall be calculated, return rightaway and don't do anything
96  if (not m_param_calculateROI) {
97  return;
98  }
99 
100  Super::initialize();
101 
102  m_storePXDIntercepts.registerInDataStore(m_param_storePXDInterceptsName);
103  m_storeROIs.registerInDataStore(m_param_storeROIsName);
104 
105  if (m_param_minimumROISizeUL1 < 0 or m_param_minimumROISizeUL2 < 0 or
106  m_param_minimumROISizeVL1 < 0 or m_param_minimumROISizeVL2 < 0 or
107  m_param_multiplierUL1 < 0 or m_param_multiplierUL2 < 0 or
108  m_param_multiplierVL1 < 0 or m_param_multiplierVL2 < 0 or
109  m_param_tolerancePhi < 0 or m_param_toleranceZ < 0) {
110  B2ERROR("Please check the ROI size parameters. "
111  "None of minimumROISizeUL1, minimumROISizeUL2, minimumROISizeVL1, minimumROISizeVL2, "
112  "multiplierUL1, multiplierUL2, multiplierVL1, multiplierVL2, overlapU, overlapV must be < 0!");
113  }
114 };
115 
116 void ROIFinder::beginRun()
117 {
118  // If no ROIs shall be calculated, return rightaway and don't do anything
119  if (not m_param_calculateROI) {
120  return;
121  }
122 
123  Super::beginRun();
124 
125  m_bFieldZ = BFieldManager::getField(0, 0, 0).Z() / Unit::T;
126 
127  DBObjPtr<BeamSpot> beamSpotDB;
128  if (beamSpotDB.isValid()) {
129  m_BeamSpotPosition = (*beamSpotDB).getIPPosition();
130  } else {
131  m_BeamSpotPosition.SetXYZ(0., 0., 0.);
132  }
133 }
134 
135 
136 void ROIFinder::beginEvent()
137 {
138  // If no ROIs shall be calculated, return rightaway and don't do anything
139  if (not m_param_calculateROI) {
140  return;
141  }
142 
143  Super::beginEvent();
144 }
145 
146 void ROIFinder::apply(const std::vector<SpacePointTrackCand>& finalTracks)
147 {
148  // If no ROIs shall be calculated, return rightaway and don't do anything
149  if (not m_param_calculateROI) {
150  return;
151  }
152 
153  for (auto& track : finalTracks) {
154  // do nothing if the SpacePointTrackCand is not active
155  if (!track.hasRefereeStatus(SpacePointTrackCand::c_isActive)) {
156  continue;
157  }
158 
159  std::vector<PXDIntercept> thisTracksIntercepts;
160  thisTracksIntercepts.reserve(8);
161 
162  const B2Vector3D& momentumEstimate = track.getMomSeed();
163 
164  const double trackPhi = momentumEstimate.Phi();
165  const double trackTheta = momentumEstimate.Theta();
166  const double tanTrackLambda = tan(M_PI_2 - trackTheta);
167  const double trackRadius = momentumEstimate.Perp() / (0.00299792458 * m_bFieldZ) ;
168  const double trackCharge = track.getChargeSeed();
169 
171  for (int layer = 1; layer <= 2; layer++) {
172  const double sensorPerpRadius = m_const_layerRadius[layer - 1];
173 
175  for (int ladder = 1; ladder <= (layer == 1 ? 8 : 12); ladder++) {
176  const double sensorPhi = (layer == 1) ? m_const_ladderPhiL1[ladder - 1] : m_const_ladderPhiL2[ladder - 1];
177  const double rotatedBeamSpotX = m_BeamSpotPosition.X() * cos(sensorPhi) + m_BeamSpotPosition.Y() * sin(sensorPhi);
178  const double rotatedBeamSpotY = -m_BeamSpotPosition.X() * sin(sensorPhi) + m_BeamSpotPosition.Y() * cos(sensorPhi);
179 
180  // in the rotated coordinate the sensor is perpendicular to the x axis at position sensorLocalX
181  const double sensorLocalX = sensorPerpRadius - rotatedBeamSpotX;
182 
183  double phiDiff = trackPhi - sensorPhi;
184  if (phiDiff < -M_PI) {
185  phiDiff += 2. * M_PI;
186  }
187  if (phiDiff > M_PI) {
188  phiDiff -= 2. * M_PI;
189  }
190 
191  // Don't try to extrapolate if track direction and sensor are too different (in phi)
192  // this should speed up the calculation as wrong combinations are not checked at all.
193  // Two values to check both the outgoing (0.3) and incoming (0.8) arm.
194  if (fabs(phiDiff) > 0.3 * M_PI /*and fabs(phiDiff) < 0.8 * M_PI*/) {
195  continue;
196  }
197 
198  // relative phi value of the track center compared to the rotated
199  // coordinate system defined by the (rotated) line perpendicular
200  // to the sensor (with length sensorPerpRadius)
201  double relTrackCenterPhi = 0;
202  if (trackCharge < 0) {
203  relTrackCenterPhi = trackPhi - M_PI_2 - sensorPhi;
204  } else if (trackCharge > 0) {
205  relTrackCenterPhi = trackPhi + M_PI_2 - sensorPhi;
206  }
207  const double xCenter = trackRadius * cos(relTrackCenterPhi);
208  const double yCenter = trackRadius * sin(relTrackCenterPhi);
209 
210  // continue if radicant of sqrt is negative
211  if ((trackRadius * trackRadius - (sensorLocalX - xCenter) * (sensorLocalX - xCenter)) < 0) {
212  continue;
213  }
214  const double ytmp = sqrt(trackRadius * trackRadius - (sensorLocalX - xCenter) * (sensorLocalX - xCenter));
215  const double yplus = yCenter + ytmp + rotatedBeamSpotY;
216  const double yminus = yCenter - ytmp + rotatedBeamSpotY;
217 
218  const double correctionterm = (m_param_radiusCorrectionFactor * trackCharge / trackRadius) +
219  m_param_sinPhiCorrectionFactor * sin(trackPhi) +
220  m_param_cosPhiCorrectionFactor * cos(trackPhi);
221 
222  const double localUPositionPlus = yplus - m_const_shiftY + correctionterm;
223  const double localUPositionMinus = yminus - m_const_shiftY + correctionterm;
224  const double toleranceRPhi = m_param_tolerancePhi * sensorLocalX;
225 
226  // if the hit for sure is out of reach of the current ladder, continue
227  if (not(yplus >= m_const_sensorMinY - toleranceRPhi and yplus <= m_const_sensorMaxY + toleranceRPhi) and
228  not(yminus >= m_const_sensorMinY - toleranceRPhi and yminus <= m_const_sensorMaxY + toleranceRPhi)) {
229  continue;
230  }
231 
232  // estimate the z coordinate of the extrapolation on this layer
233  const double z = sensorLocalX * tanTrackLambda - m_BeamSpotPosition.Z();
234 
236  for (int sensor = 1; sensor <= 2; sensor++) {
237 
238  const double shiftZ = (layer == 1) ? m_const_centerZShiftLayer1[sensor - 1] : m_const_centerZShiftLayer2[sensor - 1];
239 
240  double localVPosition = z - shiftZ;
241  // check whether z intersection possibly is on sensor to be checked, only continue with the rest of calculations if that's the case
242  if (localVPosition >= ((-m_const_activeSensorLength[layer - 1] / 2.0) - m_param_toleranceZ) and
243  localVPosition <= ((m_const_activeSensorLength[layer - 1] / 2.0) + m_param_toleranceZ)) {
244 
245  const VxdID sensorID = VxdID(layer, ladder, sensor);
246 
247  // double localVPosition = z - shiftZ;
248  // check for first option of the intersection
249  if (localUPositionPlus >= -m_const_activeSensorWidth / 2.0 - toleranceRPhi and
250  localUPositionPlus <= m_const_activeSensorWidth / 2.0 + toleranceRPhi) {
251  PXDIntercept intercept;
252  intercept.setCoorU(localUPositionPlus);
253  intercept.setCoorV(localVPosition);
254  intercept.setVxdID(sensorID);
255  m_storePXDIntercepts.appendNew(intercept);
256  thisTracksIntercepts.push_back(intercept);
257  }
258  // check for second option of the intersection
259  if (localUPositionMinus >= -m_const_activeSensorWidth / 2.0 - toleranceRPhi and
260  localUPositionMinus <= m_const_activeSensorWidth / 2.0 + toleranceRPhi) {
261  PXDIntercept intercept;
262  intercept.setCoorU(localUPositionMinus);
263  intercept.setCoorV(localVPosition);
264  intercept.setVxdID(sensorID);
265  m_storePXDIntercepts.appendNew(intercept);
266  thisTracksIntercepts.push_back(intercept);
267  }
268  }
269  }
270  }
271  }
272 
273  const double omega = 1. / trackRadius;
274  unsigned short uSizeL1 = (unsigned short)(m_param_multiplierUL1 * omega + m_param_minimumROISizeUL1);
275  unsigned short uSizeL2 = (unsigned short)(m_param_multiplierUL2 * omega + m_param_minimumROISizeUL2);
276  unsigned short vSizeL1 = (unsigned short)((1. + fabs(tanTrackLambda) * m_param_multiplierVL1) * m_param_minimumROISizeVL1);
277  unsigned short vSizeL2 = (unsigned short)((1. + fabs(tanTrackLambda) * m_param_multiplierVL2) * m_param_minimumROISizeVL2);
278  for (auto& intercept : thisTracksIntercepts) {
279  const VxdID& interceptSensorID = intercept.getSensorID();
280 
281  double uCoordinate = intercept.getCoorU();
282  double vCoordinate = intercept.getCoorV();
283 
284  const PXD::SensorInfo* currentSensor = dynamic_cast<const PXD::SensorInfo*>(&VXD::GeoCache::get(interceptSensorID));
285 
286  int interceptUCell = currentSensor->getUCellID(uCoordinate, vCoordinate, false);
287  int interceptVCell = currentSensor->getVCellID(vCoordinate, false);
288  int nUCells = currentSensor->getUCells();
289  int nVCells = currentSensor->getVCells();
290 
291  unsigned short uSize = (interceptSensorID.getLayerNumber() == 1 ? uSizeL1 : uSizeL2);
292  unsigned short vSize = (interceptSensorID.getLayerNumber() == 1 ? vSizeL1 : vSizeL2);
293  if (uSize > m_param_maximumROISizeU) {
294  uSize = m_param_maximumROISizeU;
295  }
296  if (vSize > m_param_maximumROISizeV) {
297  vSize = m_param_maximumROISizeV;
298  }
299 
301  short uCellDownLeft = interceptUCell - uSize / 2;
302  short vCellDownLeft = interceptVCell - vSize / 2;
303 
305  short uCellUpRight = interceptUCell + uSize / 2;
306  short vCellUpRight = interceptVCell + vSize / 2;
307 
308  if (uCellDownLeft >= nUCells or vCellDownLeft >= nVCells or uCellUpRight < 0 or vCellUpRight < 0) {
309  continue;
310  }
311 
312  if (uCellDownLeft < 0) {
313  uCellDownLeft = 0;
314  }
315  if (vCellDownLeft < 0) {
316  vCellDownLeft = 0;
317  }
318 
319  // minimum cell id is 0, maximum is nCells - 1
320  if (uCellUpRight >= nUCells) {
321  uCellUpRight = nUCells - 1;
322  }
323  if (vCellUpRight >= nVCells) {
324  vCellUpRight = nVCells - 1;
325  }
326 
327  m_storeROIs.appendNew(ROIid(uCellDownLeft, uCellUpRight, vCellDownLeft, vCellUpRight, interceptSensorID));
328  }
329 
330  }
331 }
332 
DataType Phi() const
The azimuth angle.
Definition: B2Vector3.h:136
DataType Theta() const
The polar angle.
Definition: B2Vector3.h:138
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:185
bool isValid() const
Check whether a valid object was obtained from the database.
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
The Module parameter list class.
PXDIntercept stores the U,V coordinates and uncertainties of the intersection of a track with an PXD ...
Definition: PXDIntercept.h:22
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
Definition: SensorInfo.h:23
ROIid stores the U and V ids and the sensor id of the Region Of Interest.
Definition: ROIid.h:25
@ c_isActive
bit 11: SPTC is active (i.e.
static const double T
[tesla]
Definition: Unit.h:120
void setVxdID(VxdID::baseType user_vxdID)
set the sensor ID
Definition: VXDIntercept.h:75
void setCoorU(double user_coorU)
set the U coordinate of the intercept
Definition: VXDIntercept.h:68
void setCoorV(double user_coorV)
set the V coordinate of the intercept
Definition: VXDIntercept.h:69
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:139
int getVCells() const
Return number of pixel/strips in v direction.
int getUCells() const
Return number of pixel/strips in u direction.
int getVCellID(double v, bool clamp=false) const
Return the corresponding pixel/strip ID of a given v coordinate.
int getUCellID(double u, double v=0, bool clamp=false) const
Return the corresponding pixel/strip ID of a given u coordinate.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
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.
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
Abstract base class for different kinds of events.