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 tan(double a)
tan for double
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.