8 #include <tracking/vxdHoughTracking/findlets/ROIFinder.h>
9 #include <tracking/vxdHoughTracking/findlets/RawTrackCandCleaner.icc.h>
10 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
11 #include <tracking/trackFindingVXD/trackQualityEstimators/QualityEstimatorCircleFit.h>
12 #include <tracking/trackFindingVXD/trackQualityEstimators/QualityEstimatorRiemannHelixFit.h>
13 #include <tracking/trackFindingVXD/trackQualityEstimators/QualityEstimatorTripletFit.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/core/ModuleParamList.h>
16 #include <framework/geometry/BFieldManager.h>
17 #include <framework/geometry/B2Vector3.h>
18 #include <framework/database/DBObjPtr.h>
19 #include <mdst/dbobjects/BeamSpot.h>
20 #include <pxd/geometry/SensorInfo.h>
21 #include <vxd/geometry/GeoCache.h>
24 using namespace TrackFindingCDC;
25 using namespace vxdHoughTracking;
27 ROIFinder::~ROIFinder() =
default;
29 ROIFinder::ROIFinder()
33 void ROIFinder::exposeParameters(
ModuleParamList* moduleParamList,
const std::string& prefix)
35 Super::exposeParameters(moduleParamList, prefix);
37 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"calculateROI"), m_calculateROI,
38 "Calculate PXDIntercepts and ROIs in this findlet based on a simple circle extrapolation (r-phi) and straigh line extrapolation (z, theta)?",
41 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"storePXDInterceptsName"), m_storePXDInterceptsName,
42 "Name of the PXDIntercepts StoreArray produced by SVDHoughTracking using a simple circle extrapolation in r-phi and a straight line extrapolation in theta.",
43 m_storePXDInterceptsName);
45 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"storeROIsName"), m_storeROIsName,
46 "Name of the ROIs StoreArray produced by SVDHoughTracking using a simple circle extrapolation in r-phi and a straight line extrapolation in theta.",
49 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"tolerancePhi"), m_tolerancePhi,
50 "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.",
52 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"toleranceZ"), m_toleranceZ,
53 "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.",
56 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"radiusCorrectionFactorL1"), m_radiusCorrectionFactorL1,
57 "Correct charge-dependent bias of the extrapolated hit on L1 with radiusCorrectionFactor * trackCharge / trackRadius.",
58 m_radiusCorrectionFactorL1);
59 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"radiusCorrectionFactorL2"), m_radiusCorrectionFactorL2,
60 "Correct charge-dependent bias of the extrapolated hit on L2 with radiusCorrectionFactor * trackCharge / trackRadius.",
61 m_radiusCorrectionFactorL2);
62 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"sinPhiCorrectionFactor"), m_sinPhiCorrectionFactor,
63 "Correct sin(trackPhi) dependent bias with sinPhiCorrectionFactor * sin(trackPhi).",
64 m_sinPhiCorrectionFactor);
65 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"cosPhiCorrectionFactor"), m_cosPhiCorrectionFactor,
66 "Correct cos(trackPhi) dependent bias with cosPhiCorrectionFactor * cos(trackPhi).",
67 m_cosPhiCorrectionFactor);
69 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"zPositionCorrectionFactor"), m_zPositionCorrectionFactor,
70 "Correction factor for the extrapolated z position.",
71 m_zPositionCorrectionFactor);
73 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"minimumROISizeUL1"), m_minimumROISizeUL1,
74 "Minimum ROI size (in pixel) in u direction on L1.", m_minimumROISizeUL1);
75 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"minimumROISizeVL1"), m_minimumROISizeVL1,
76 "Minimum ROI size (in pixel) in v direction on L1.", m_minimumROISizeVL1);
77 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"minimumROISizeUL2"), m_minimumROISizeUL2,
78 "Minimum ROI size (in pixel) in u direction on L2.", m_minimumROISizeUL2);
79 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"minimumROISizeVL2"), m_minimumROISizeVL2,
80 "Minimum ROI size (in pixel) in v direction on L2.", m_minimumROISizeVL2);
82 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"multiplierUL1"), m_multiplierUL1,
83 "Multiplier term for ROI size estimation for L1 u direction. Usage: multiplierUL1 * 1/R + minimumROISizeUL1, with R in cm.",
85 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"multiplierUL2"), m_multiplierUL2,
86 "Multiplier term for ROI size estimation for L2 u direction. Usage: multiplierUL2 * 1/R + minimumROISizeUL2, with R in cm.",
88 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"multiplierVL1"), m_multiplierVL1,
89 "Multiplier term for ROI size estimation for L1 v direction. Usage: (1 + abs(tan(lambda)) * multiplierVL1) + minimumROISizeVL1.",
91 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"multiplierVL2"), m_multiplierVL2,
92 "Multiplier term for ROI size estimation for L2 v direction. Usage: (1 + abs(tan(lambda)) * multiplierVL2) + minimumROISizeVL2.",
95 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"maximumROISizeU"), m_maximumROISizeU,
96 "Maximum ROI size in u.", m_maximumROISizeU);
97 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"maximumROISizeV"), m_maximumROISizeV,
98 "Maximum ROI size in v.", m_maximumROISizeV);
101 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"refit"), m_refit,
102 "Refit the track with trackQualityEstimationMethod?", m_refit);
103 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"addVirtualIP"), m_addVirtualIP,
104 "Add virtual IP to fit the tracks again for ROI creation?", m_addVirtualIP);
105 moduleParamList->
addParameter(TrackFindingCDC::prefixed(prefix,
"ROIFitMethod"), m_ROIFitMethod,
106 "Identifier which fit method to use. Valid identifiers are: [circleFit, tripletFit, helixFit]",
112 void ROIFinder::initialize()
115 if (not m_calculateROI) {
121 m_storePXDIntercepts.registerInDataStore(m_storePXDInterceptsName);
122 m_storeROIs.registerInDataStore(m_storeROIsName);
124 if (m_minimumROISizeUL1 < 0 or m_minimumROISizeUL2 < 0 or
125 m_minimumROISizeVL1 < 0 or m_minimumROISizeVL2 < 0 or
126 m_multiplierUL1 < 0 or m_multiplierUL2 < 0 or
127 m_multiplierVL1 < 0 or m_multiplierVL2 < 0 or
128 m_tolerancePhi < 0 or m_toleranceZ < 0) {
129 B2ERROR(
"Please check the ROI size parameters. "
130 "None of minimumROISizeUL1, minimumROISizeUL2, minimumROISizeVL1, minimumROISizeVL2, "
131 "multiplierUL1, multiplierUL2, multiplierVL1, multiplierVL2, overlapU, overlapV must be < 0!");
134 if (m_ROIFitMethod ==
"tripletFit") {
135 m_estimator = std::make_unique<QualityEstimatorTripletFit>();
136 }
else if (m_ROIFitMethod ==
"circleFit") {
137 m_estimator = std::make_unique<QualityEstimatorCircleFit>();
138 }
else if (m_ROIFitMethod ==
"helixFit") {
139 m_estimator = std::make_unique<QualityEstimatorRiemannHelixFit>();
141 B2ASSERT(
"QualityEstimator could not be initialized with method: " << m_ROIFitMethod, m_estimator);
145 void ROIFinder::beginRun()
148 if (not m_calculateROI) {
155 m_estimator->setMagneticFieldStrength(m_bFieldZ);
159 m_BeamSpotPosition = (*beamSpotDB).getIPPosition();
160 const TMatrixDSym posErr = (*beamSpotDB).getIPPositionCovMatrix();
161 m_BeamSpotPositionError.SetXYZ(
sqrt(posErr[0][0]),
sqrt(posErr[1][1]),
sqrt(posErr[2][2]));
163 m_BeamSpotPosition.SetXYZ(0., 0., 0.);
164 m_BeamSpotPositionError.SetXYZ(0., 0., 0.);
169 void ROIFinder::beginEvent()
172 if (not m_calculateROI) {
179 void ROIFinder::apply(
const std::vector<SpacePointTrackCand>& finalTracks)
182 if (not m_calculateROI) {
186 for (
auto& track : finalTracks) {
194 auto sortedHits = track.getSortedHits();
196 if (m_addVirtualIP) {
197 SpacePoint virtualIPSpacePoint =
SpacePoint(m_BeamSpotPosition, m_BeamSpotPositionError, {0.5, 0.5}, {
false,
false},
199 sortedHits.push_back(&virtualIPSpacePoint);
202 std::sort(sortedHits.begin(), sortedHits.end(),
203 [](
const SpacePoint * a,
const SpacePoint * b) {return a->getPosition().Perp() < b->getPosition().Perp(); });
205 refittedTrackEstimate = m_estimator->estimateQualityAndProperties(sortedHits);
208 std::vector<PXDIntercept> thisTracksIntercepts;
209 thisTracksIntercepts.reserve(8);
211 B2Vector3D momentumEstimate = track.getMomSeed();
213 momentumEstimate = *refittedTrackEstimate.
p;
216 const double trackPhi = momentumEstimate.
Phi();
217 const double trackTheta = momentumEstimate.
Theta();
218 const double tanTrackLambda =
tan(M_PI_2 - trackTheta);
219 const double trackRadius = momentumEstimate.
Perp() / (0.00299792458 * m_bFieldZ) ;
220 const double trackCharge = track.getChargeSeed();
223 for (
int layer = 1; layer <= 2; layer++) {
224 const double sensorPerpRadius = c_layerRadius[layer - 1];
227 for (
int ladder = 1; ladder <= (layer == 1 ? 8 : 12); ladder++) {
228 const double sensorPhi = (layer == 1) ? c_ladderPhiL1[ladder - 1] : c_ladderPhiL2[ladder - 1];
229 const double rotatedBeamSpotX = m_BeamSpotPosition.X() * cos(sensorPhi) + m_BeamSpotPosition.Y() * sin(sensorPhi);
230 const double rotatedBeamSpotY = -m_BeamSpotPosition.X() * sin(sensorPhi) + m_BeamSpotPosition.Y() * cos(sensorPhi);
233 const double sensorLocalX = sensorPerpRadius - rotatedBeamSpotX;
235 double phiDiff = trackPhi - sensorPhi;
236 if (phiDiff < -M_PI) {
237 phiDiff += 2. * M_PI;
239 if (phiDiff > M_PI) {
240 phiDiff -= 2. * M_PI;
246 if (fabs(phiDiff) > 0.25 * M_PI and fabs(phiDiff) < 0.75 * M_PI) {
249 if (fabs(phiDiff) > 0.75 * M_PI and fabs(tanTrackLambda) > 0.2 ) {
257 double relTrackCenterPhi = 0;
258 if (trackCharge < 0) {
259 relTrackCenterPhi = trackPhi - M_PI_2 - sensorPhi;
260 }
else if (trackCharge > 0) {
261 relTrackCenterPhi = trackPhi + M_PI_2 - sensorPhi;
263 const double xCenter = trackRadius * cos(relTrackCenterPhi);
264 const double yCenter = trackRadius * sin(relTrackCenterPhi);
267 if ((trackRadius * trackRadius - (sensorLocalX - xCenter) * (sensorLocalX - xCenter)) < 0) {
270 const double ytmp =
sqrt(trackRadius * trackRadius - (sensorLocalX - xCenter) * (sensorLocalX - xCenter));
271 const double yplus = yCenter + ytmp + rotatedBeamSpotY;
272 const double yminus = yCenter - ytmp + rotatedBeamSpotY;
274 const double correctionterm = ((layer == 1 ? m_radiusCorrectionFactorL1 : m_radiusCorrectionFactorL2) * trackCharge /
276 m_sinPhiCorrectionFactor * sin(trackPhi) +
277 m_cosPhiCorrectionFactor * cos(trackPhi);
279 const double localUPositionPlus = yplus - c_shiftY + correctionterm;
280 const double localUPositionMinus = yminus - c_shiftY + correctionterm;
281 const double toleranceRPhi = m_tolerancePhi * sensorLocalX;
284 if (not(yplus >= c_sensorMinY - toleranceRPhi and yplus <= c_sensorMaxY + toleranceRPhi) and
285 not(yminus >= c_sensorMinY - toleranceRPhi and yminus <= c_sensorMaxY + toleranceRPhi)) {
290 const double z = sensorLocalX * tanTrackLambda - m_BeamSpotPosition.Z();
291 const double zPlus =
sqrt(sensorLocalX * sensorLocalX + yplus * yplus) * tanTrackLambda * m_zPositionCorrectionFactor -
292 m_BeamSpotPosition.Z();
293 const double zMinus =
sqrt(sensorLocalX * sensorLocalX + yminus * yminus) * tanTrackLambda * m_zPositionCorrectionFactor -
294 m_BeamSpotPosition.Z();
297 for (
int sensor = 1; sensor <= 2; sensor++) {
299 const double shiftZ = (layer == 1) ? c_centerZShiftLayer1[sensor - 1] : c_centerZShiftLayer2[sensor - 1];
301 double localVPosition = z - shiftZ;
302 double localVPositionPlus = zPlus - shiftZ;
303 double localVPositionMinus = zMinus - shiftZ;
305 if (localVPosition >= ((-c_activeSensorLength[layer - 1] / 2.0) - m_toleranceZ) and
306 localVPosition <= ((c_activeSensorLength[layer - 1] / 2.0) + m_toleranceZ)) {
308 const VxdID sensorID =
VxdID(layer, ladder, sensor);
311 if (localUPositionPlus >= -c_activeSensorWidth / 2.0 - toleranceRPhi and
312 localUPositionPlus <= c_activeSensorWidth / 2.0 + toleranceRPhi) {
314 intercept.
setCoorU(localUPositionPlus);
315 intercept.
setCoorV(localVPositionPlus);
317 m_storePXDIntercepts.appendNew(intercept);
318 thisTracksIntercepts.push_back(intercept);
321 if (localUPositionMinus >= -c_activeSensorWidth / 2.0 - toleranceRPhi and
322 localUPositionMinus <= c_activeSensorWidth / 2.0 + toleranceRPhi) {
324 intercept.
setCoorU(localUPositionMinus);
325 intercept.
setCoorV(localVPositionMinus);
327 m_storePXDIntercepts.appendNew(intercept);
328 thisTracksIntercepts.push_back(intercept);
335 const double omega = 1. / trackRadius;
336 unsigned short uSizeL1 = (
unsigned short)(m_multiplierUL1 * omega + m_minimumROISizeUL1);
337 unsigned short uSizeL2 = (
unsigned short)(m_multiplierUL2 * omega + m_minimumROISizeUL2);
338 unsigned short vSizeL1 = (
unsigned short)((1. + fabs(tanTrackLambda) * m_multiplierVL1) * m_minimumROISizeVL1);
339 unsigned short vSizeL2 = (
unsigned short)((1. + fabs(tanTrackLambda) * m_multiplierVL2) * m_minimumROISizeVL2);
340 for (
auto& intercept : thisTracksIntercepts) {
341 const VxdID& interceptSensorID = intercept.getSensorID();
343 double uCoordinate = intercept.getCoorU();
344 double vCoordinate = intercept.getCoorV();
348 int interceptUCell = currentSensor->
getUCellID(uCoordinate, vCoordinate,
false);
349 int interceptVCell = currentSensor->
getVCellID(vCoordinate,
false);
350 int nUCells = currentSensor->
getUCells();
351 int nVCells = currentSensor->
getVCells();
353 unsigned short uSize = (interceptSensorID.
getLayerNumber() == 1 ? uSizeL1 : uSizeL2);
354 unsigned short vSize = (interceptSensorID.
getLayerNumber() == 1 ? vSizeL1 : vSizeL2);
355 if (uSize > m_maximumROISizeU) {
356 uSize = m_maximumROISizeU;
358 if (vSize > m_maximumROISizeV) {
359 vSize = m_maximumROISizeV;
363 short uCellDownLeft = interceptUCell - uSize / 2;
364 short vCellDownLeft = interceptVCell - vSize / 2;
367 short uCellUpRight = interceptUCell + uSize / 2;
368 short vCellUpRight = interceptVCell + vSize / 2;
370 if (uCellDownLeft >= nUCells or vCellDownLeft >= nVCells or uCellUpRight < 0 or vCellUpRight < 0) {
374 if (uCellDownLeft < 0) {
377 if (vCellDownLeft < 0) {
382 if (uCellUpRight >= nUCells) {
383 uCellUpRight = nUCells - 1;
385 if (vCellUpRight >= nVCells) {
386 vCellUpRight = nVCells - 1;
389 m_storeROIs.appendNew(
ROIid(uCellDownLeft, uCellUpRight, vCellDownLeft, vCellUpRight, interceptSensorID));
DataType Phi() const
The azimuth angle.
DataType Theta() const
The polar angle.
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
bool isValid() const
Check whether a valid object was obtained from the database.
Class for accessing objects in the database.
The Module parameter list class.
PXDIntercept stores the U,V coordinates and uncertainties of the intersection of a track with an PXD ...
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
ROIid stores the U and V ids and the sensor id of the Region Of Interest.
@ c_isActive
bit 11: SPTC is active (i.e.
SpacePoint typically is build from 1 PXDCluster or 1-2 SVDClusters.
static const double T
[tesla]
void setVxdID(VxdID::baseType user_vxdID)
set the sensor ID
void setCoorU(double user_coorU)
set the U coordinate of the intercept
void setCoorV(double user_coorV)
set the V coordinate of the intercept
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
int getVCells() const
Return number of pixel/strips in v direction.
@ VXD
Any type of VXD Sensor.
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.
baseType getLayerNumber() const
Get the layer id.
void addParameter(const std::string &name, T ¶mVariable, 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.
double sqrt(double a)
sqrt for double
double tan(double a)
tan for double
Abstract base class for different kinds of events.
Container for complete fit/estimation results.
std::optional< B2Vector3D > p
momentum vector estimate from the QE