8#include <tracking/modules/kinkFinder/KinkFinderModule.h>
10#include <framework/gearbox/Const.h>
11#include <framework/logging/Logger.h>
12#include <framework/dataobjects/Helix.h>
13#include <framework/geometry/BFieldManager.h>
15#include <mdst/dataobjects/HitPatternCDC.h>
16#include <mdst/dataobjects/TrackFitResult.h>
18#include <genfit/MeasuredStateOnPlane.h>
27 setDescription(
"This is a Kink finder module which preselects mother and daughter candidate tracks and matches them "
28 "and fits a vertex for each pair. Depending on the outcome of each fit, a corresponding "
29 "``Belle2::Kink`` is stored or not.\n\n"
30 "The parameters of the ``KinkFinder`` are stored as payloads in ``KinkFinderParameters``.\n\n"
31 "A loose cut on the pair is applied before the fit; then, a vertex fit is performed, and only pairs "
32 "passing a chi^2 (``KinkFinderParameters::m_vertexChi2Cut``) and distance "
33 "(``KinkFinderParameters::m_vertexDistanceCut``) are stored as ``Belle2::Kink``.\n\n"
34 "If a corresponding ``KinkFitter`` mode is ON, hits are reassigned between mother and daughter tracks "
35 "to improve the resolutions and efficiency. If a corresponding ``KinkFitter`` mode is ON, the track "
36 "pair is also fitted as one track and a special flag is filled based on the result to suppress the clones.\n\n"
37 "If a corresponding ``KinkFitter`` mode is ON, ``KinkFinder`` preselects track candidates "
38 "that might be formed from two kink tracks, and ``KinkFitter`` splits such tracks. "
39 "After that the result is stored in ``Belle2::Kink``.");
45 "RecoTrack StoreArray name (input)", std::string(
""));
49 "RecoTrack StoreArray name (used for track refitting)", std::string(
"RecoTracksKinkTmp"));
53 "Belle2::TrackFitResult StoreArray name (in- and output).\n"
54 "Note that the Kinks use pointers indices into these arrays, so all hell may break loose, "
55 "if you change this.", std::string(
""));
57 "Belle2::Track StoreArray name (input).\n"
58 "Note that the Kinks use pointers indices into these arrays, so all hell may break loose, "
59 "if you change this.", std::string(
""));
71 m_tracks.requireRelationTo(recoTracks);
95 B2FATAL(
"KinkFinder parameters are not available.");
107 B2DEBUG(29,
m_tracks.getEntries() <<
" tracks in event.");
110 std::vector<const Track*> tracksMother;
111 tracksMother.reserve(
m_tracks.getEntries());
113 std::vector<const Track*> tracksDaughter;
114 tracksDaughter.reserve(
m_tracks.getEntries());
116 for (
const auto& track :
m_tracks) {
118 B2ASSERT(
"No RecoTrack available for given Track.", recoTrack);
126 ((recoHitsInformation.back())->getTrackingDetector() == RecoHitInformation::RecoHitDetector::c_SVD ||
127 (recoHitsInformation.back())->getTrackingDetector() == RecoHitInformation::RecoHitDetector::c_PXD))
130 bool trackChosen =
false;
133 tracksMother.push_back(&track);
138 const short filterFlag = 7;
144 tracksDaughter.push_back(&track);
149 const short filterFlag = 8;
156 const short filterFlag = 9;
162 if (tracksMother.empty() || tracksDaughter.empty()) {
163 B2DEBUG(29,
"No interesting track pairs found. Number of selected tracksMother: " << tracksMother.size() <<
164 ", tracksDaughter " << tracksDaughter.size());
169 for (
auto& trackMother : tracksMother) {
170 for (
auto& trackDaughter : tracksDaughter) {
172 if (!filterFlag)
continue;
173 B2DEBUG(29,
"Found kink candidate with filterFlag " << filterFlag);
174 fitAndStore(trackMother, trackDaughter, filterFlag);
183 B2INFO(
"===KinkFinder summary===========================================================");
184 B2INFO(
"In total " <<
m_allStored <<
" kinks saved. Among them");
185 B2INFO(
"track pairs with close endpoints: " <<
m_f1Stored <<
";");
186 B2INFO(
"track pairs with missing layers between their endpoints (Helix extrapolation selection): " <<
m_f2Stored <<
";");
187 B2INFO(
"split track chosen from mother candidates: " <<
m_f3Stored <<
";");
188 B2INFO(
"split track chosen from daughter candidates: " <<
m_f4Stored <<
";");
189 B2INFO(
"split track chosen from tracks not passing mother/daughter preselection " <<
m_f5Stored <<
".");
242 if (nCDCHits && !
ifInCDC(posLast))
return false;
258 if (fabs(trackFitResult->getD0()) > 1)
return false;
298 if (nFittedCDCHits < 5)
return false;
307 if (fabs(trackFitResult->
getD0()) > 2)
return false;
315 constexpr double M_PI_over_6 = M_PI / 6.;
316 const double cos_M_PI_over_6 = cos(M_PI_over_6);
326 if (motherRecoTrack == daughterRecoTrack)
return 0;
330 const ROOT::Math::XYZVector daughterPosFirst(daughterRecoTrack->getMeasuredStateOnPlaneFromFirstHit().getPos());
331 if ((daughterPosFirst - motherPosLast).Mag2() < precutDistanceSquared)
return 1;
334 const ROOT::Math::XYZVector daughterPosLast(daughterRecoTrack->getMeasuredStateOnPlaneFromLastHit().getPos());
335 if ((daughterPosLast - motherPosLast).Mag2() < precutDistanceSquared)
return 2;
341 if (daughterPosLast.Unit().Dot(motherPosLast.Unit()) > cos_M_PI_over_6 ||
342 daughterPosFirst.Unit().Dot(motherPosLast.Unit()) > cos_M_PI_over_6 ||
343 fabs(daughterPosLast.Phi() - motherPosLast.Phi()) < M_PI_over_6 ||
344 fabs(daughterPosFirst.Phi() - motherPosLast.Phi()) < M_PI_over_6) {
346 const ROOT::Math::XYZVector daughterPosClosestToMotherPosLast(daughterRecoTrack->getMeasuredStateOnPlaneFromFirstHit().getPos());
347 const ROOT::Math::XYZVector daughterMomClosestToMotherPosLast(daughterRecoTrack->getMeasuredStateOnPlaneFromFirstHit().getMom());
350 Helix daughterHelixClosestToMotherPosLast(daughterPosClosestToMotherPosLast,
351 daughterMomClosestToMotherPosLast,
352 static_cast<short>(daughterRecoTrack->getTrackFitStatus()->getCharge()),
354 daughterHelixClosestToMotherPosLast.passiveMoveBy(motherPosLast);
356 if ((daughterHelixClosestToMotherPosLast.getD0() * daughterHelixClosestToMotherPosLast.getD0() +
357 daughterHelixClosestToMotherPosLast.getZ0() * daughterHelixClosestToMotherPosLast.getZ0()) <
358 precutDistanceSquared)
363 if ((daughterPosFirst - motherPosLast).Perp2() < precutDistance2DSquared)
367 if ((daughterPosLast - motherPosLast).Perp2() < precutDistance2DSquared)
372 if (daughterPosLast.Unit().Dot(motherPosLast.Unit()) > cos_M_PI_over_6 ||
373 daughterPosFirst.Unit().Dot(motherPosLast.Unit()) > cos_M_PI_over_6 ||
374 fabs(daughterPosLast.Phi() - motherPosLast.Phi()) < M_PI_over_6 ||
375 fabs(daughterPosFirst.Phi() - motherPosLast.Phi()) < M_PI_over_6) {
377 const ROOT::Math::XYZVector daughterPosClosestToMotherPosLast(daughterRecoTrack->getMeasuredStateOnPlaneFromFirstHit().getPos());
378 const ROOT::Math::XYZVector daughterMomClosestToMotherPosLast(daughterRecoTrack->getMeasuredStateOnPlaneFromFirstHit().getMom());
381 Helix daughterHelixClosestToMotherPosLast(daughterPosClosestToMotherPosLast,
382 daughterMomClosestToMotherPosLast,
383 static_cast<short>(daughterRecoTrack->getTrackFitStatus()->getCharge()),
385 daughterHelixClosestToMotherPosLast.passiveMoveBy(motherPosLast);
399 bool ok =
m_kinkFitter->fitAndStore(trackMother, trackDaughter, filterFlag);
402 switch (filterFlag) {
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
static const ChargedStable pion
charged pion particle
unsigned short getNHits() const
Get the total Number of CDC hits in the fit.
unsigned int m_f4Stored
counter for filter 4 saved Kinks
static constexpr double m_cdcInnerWallWithoutFirstLayer
Bigger radius of inner CDC wall [cm].
void fitAndStore(const Track *trackMother, const Track *trackDaughter, const short filterFlag)
Kink fitting and storing.
bool preFilterTracksToSplit(Track const *const track)
Check if the track can be a candidate to be split based on some simple selections.
CDCForwardBackwardWallLine m_cdcBackwardTopWall
Top part of backward CDC wall.
short isTrackPairSelected(const Track *motherTrack, const Track *daughterTrack)
Track pair preselection based on distance between two tracks with different options.
std::string m_arrayNameCopiedRecoTrack
StoreArray name of the RecoTrack used for creating copies.
std::string m_arrayNameKink
StoreArray name of the Kink (Output).
void initialize() override
Registration of StoreArrays, Relations.
static constexpr double m_cdcInnerWithFirstLayerWall
Smaller radius of inner CDC wall [cm].
bool ifInCDC(const ROOT::Math::XYZVector &pos)
Test if the point in space is inside CDC (approximate custom geometry) with respect to shifts from ou...
void event() override
Creates Belle2::Kink from Belle2::Track as described in the class documentation.
std::string m_arrayNameTFResult
StoreArray name of the TrackFitResult (In- and Output).
unsigned int m_f2Stored
counter for filter 2 saved Kinks
DBObjPtr< KinkFinderParameters > m_kinkFinderParameters
kinkFinder parameters Database ObjPtr
unsigned int m_f3Stored
counter for filter 3 saved Kinks
static constexpr double m_cdcInnerWallWithoutFirstTwoLayers
Second bigger radius of inner CDC wall [cm].
bool preFilterMotherTracks(Track const *const track)
Check if the track can be a mother candidate based on some simple selections.
static constexpr double m_svdBeforeOuterLayer
Radius between two outer SVD layers (10.4 and 13.5 cm) [cm].
void terminate() override
Prints status summary.
bool preFilterDaughterTracks(Track const *const track)
Check if the track can be a daughter candidate based on some simple selections.
unsigned int m_f1Stored
counter for filter 1 saved Kinks
void beginRun() override
Read parameters from the database and apply to KinkFitter.
StoreArray< Track > m_tracks
StoreArray of Belle2::Track.
unsigned int m_f5Stored
counter for filter 5 saved Kinks
std::string m_arrayNameRecoTrack
StoreArray name of the RecoTrack (Input).
CDCForwardBackwardWallLine m_cdcForwardBottomWall
Bottom part of forward CDC wall.
unsigned int m_allStored
counter for all saved Kinks
CDCForwardBackwardWallLine m_cdcBackwardBottomWall
Bottom part of backward CDC wall.
bool kinkFitterModeSplitTrack()
Fitter mode 4th bit responsible for turning On/Off track splitting.
static constexpr double m_cdcOuterWall
Radius of outer CDC wall [cm].
CDCForwardBackwardWallLine m_cdcForwardTopWall
Top part of forward CDC wall.
std::string m_arrayNameTrack
StoreArray name of the Belle2::Track (Input).
KinkFinderModule()
Setting of module description, parameters.
std::unique_ptr< KinkFitter > m_kinkFitter
Object containing the algorithm of Kink creation.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
This is the Reconstruction Event-Data Model Track.
bool wasFitSuccessful(const genfit::AbsTrackRep *representation=nullptr) const
Returns true if the last fit with the given representation was successful.
unsigned int getNumberOfCDCHits() const
Return the number of cdc hits.
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromLastHit(const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane for the last hit in a fit useful for extrapolation of measuremen...
bool hasTrackFitStatus(const genfit::AbsTrackRep *representation=nullptr) const
Check, if there is a fit status for the given representation or for the cardinal one.
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromFirstHit(const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane for the first hit in a fit useful for extrapolation of measureme...
const genfit::FitStatus * getTrackFitStatus(const genfit::AbsTrackRep *representation=nullptr) const
Return the track fit status for the given representation or for the cardinal one. You are not allowed...
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
Accessor to arrays stored in the data store.
Values of the result of a track fit with a given particle hypothesis.
double getD0() const
Getter for d0.
HitPatternCDC getHitPatternCDC() const
Getter for the hit pattern in the CDC;.
Class that bundles various TrackFitResults.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.
double getLine(const double x) const
Return the y value of the sloping line based on the x value.
void setLine(const double tangent, const double offset)
Set parameters of slopping line.