8#include <tracking/v0Finding/fitter/NewV0Fitter.h>
9#include <tracking/v0Finding/fitter/V0VertexFitterFactory.h>
11#include <framework/logging/Logger.h>
12#include <framework/geometry/BFieldManager.h>
13#include <tracking/trackFitting/fitter/base/TrackFitter.h>
14#include <tracking/trackFitting/trackBuilder/factories/TrackBuilder.h>
16#include <mdst/dataobjects/HitPatternVXD.h>
17#include <mdst/dataobjects/HitPatternCDC.h>
19#include <genfit/FieldManager.h>
20#include <genfit/MaterialEffects.h>
25 const std::string& v0ValidationVerticesName,
const std::string& recoTracksName,
26 const std::string& copiedRecoTracksName,
bool enableValidation)
30 B2ASSERT(
"V0Fitter: material effects not set up. Please use SetupGenfitExtrapolationModule.",
31 genfit::MaterialEffects::getInstance()->isInitialized());
32 B2ASSERT(
"V0Fitter: magnetic field not set up. Please use SetupGenfitExtrapolationModule.",
33 genfit::FieldManager::getInstance()->isInitialized());
53 const std::tuple<double, double>& invMassRangeKshort,
54 const std::tuple<double, double>& invMassRangeLambda,
55 const std::tuple<double, double>& invMassRangePhoton)
59 m_invMassCuts[22] = std::make_pair(std::get<0>(invMassRangePhoton), std::get<1>(invMassRangePhoton));
60 m_invMassCuts[310] = std::make_pair(std::get<0>(invMassRangeKshort), std::get<1>(invMassRangeKshort));
61 m_invMassCuts[3122] = std::make_pair(std::get<0>(invMassRangeLambda), std::get<1>(invMassRangeLambda));
76 B2FATAL(
"V0Fitter: given V0 hypothesis not available.");
82 bool& isForceStored,
bool& isHitRemoved)
85 isForceStored =
false;
92 if (not recoTrackPlus)
return false;
94 if (not recoTrackMinus)
return false;
100 int pdgTrackPlus = std::abs(ptypeTrackPlus.getPDGCode());
101 int pdgTrackMinus = std::abs(ptypeTrackMinus.getPDGCode());
104 int status =
vertexFit(recoTrackPlus, recoTrackMinus, pdgTrackPlus, pdgTrackMinus, v0Hypothesis);
105 if (status < 0)
return false;
109 const RecoTrack* origRecoTrackPlus = recoTrackPlus;
110 const RecoTrack* origRecoTrackMinus = recoTrackMinus;
112 while (status != 0 and counter < 5) {
116 const RecoTrack* trkPlus = recoTrackPlus;
119 if (not trkPlus)
return false;
122 const RecoTrack* trkMinus = recoTrackMinus;
125 if (not trkMinus)
return false;
128 if (trkPlus == recoTrackPlus and trkMinus == recoTrackMinus)
break;
129 status =
vertexFit(trkPlus, trkMinus, pdgTrackPlus, pdgTrackMinus, v0Hypothesis);
130 if (status < 0)
break;
131 recoTrackPlus = trkPlus;
132 recoTrackMinus = trkMinus;
135 isForceStored = (status != 0);
141 if (not fitPlus)
return false;
143 if (not fitMinus)
return false;
145 const auto* v0 =
m_v0s.appendNew(std::make_pair(trackPlus, fitPlus),
146 std::make_pair(trackMinus, fitMinus),
150 const auto* validationV0 =
m_validationV0s.appendNew(std::make_pair(trackPlus, fitPlus),
151 std::make_pair(trackMinus, fitMinus),
156 v0->addRelationTo(validationV0);
185 genfit::GFRaveVertex vert;
187 auto vertexPos = ROOT::Math::XYZVector(vert.getPos());
196 const auto& p1 = vert.getParameters(0)->getMom();
197 const auto& p2 = vert.getParameters(1)->getMom();
199 double mass1 = trackHypotheses.first.getMass();
200 double mass2 = trackHypotheses.second.getMass();
201 ROOT::Math::PxPyPzMVector fourVec1(p1.X(), p1.Y(), p1.Z(), mass1);
202 ROOT::Math::PxPyPzMVector fourVec2(p2.X(), p2.Y(), p2.Z(), mass2);
203 double invMass = (fourVec1 + fourVec2).M();
206 if (invMass < cuts.first or invMass > cuts.second)
return c_NotSelected;
220 m_trkPlus.set(recoTrackPlus, trackHypotheses.first, statePlus, plusRepresentation);
221 m_trkMinus.set(recoTrackMinus, trackHypotheses.second, stateMinus, minusRepresentation);
232 B2ERROR(
"V0Fitter: track hypothesis with closest mass not available. Should never happen!");
239 const auto& reps = gfTrack.getTrackReps();
240 for (
unsigned id = 0;
id < reps.size();
id++) {
241 if (abs(reps[
id]->getPDG()) == pdgCode) {
242 gfTrack.setCardinalRep(
id);
247 B2ERROR(
"V0Fitter: cannot set cardinal representation for PDG = " << pdgCode);
252 const genfit::GFRaveVertex& vertex)
257 double extralengthPlus = statePlus.extrapolateToPoint(vertex.getPos());
258 double extralengthMinus = stateMinus.extrapolateToPoint(vertex.getPos());
267 B2DEBUG(22,
"Could not extrapolate track to vertex.");
277 std::vector<bool> useInFit;
279 useInFit.reserve(recoHitInformations.size());
280 for (
const auto* hitInfo : recoHitInformations) useInFit.push_back(hitInfo->useInFit());
284 if (not rep)
return lastRecoTrack;
288 unsigned firstHit = 0;
289 for (
unsigned i = 0; i < recoHitInformations.size(); i++) {
290 const auto* hitInfo = recoHitInformations[i];
291 if (not hitInfo->useInFit())
continue;
294 double extraLength = state.extrapolateToPoint(
m_fittedVertex.getPos());
295 if (extraLength > 0) {
302 }
catch (NoTrackFitResult()) {
303 B2WARNING(
"V0Fitter exception: no FitterInfo assigned for TrackPoint created from this RecoHit.");
311 B2DEBUG(22,
"Could not extrapolate track to vertex when removing inner hits.");
312 return lastRecoTrack;
318 std::vector<unsigned> svdIndex;
319 for (
unsigned i = 0; i < useInFit.size(); i++) {
320 if (not useInFit[i])
continue;
321 const auto* hitInfo = recoHitInformations[i];
322 if (hitInfo->getTrackingDetector() == RecoHitInformation::c_SVD) svdIndex.push_back(i);
325 if (not svdIndex.empty() and svdIndex.size() < 3) {
326 for (
unsigned i : svdIndex) {
333 if (removedHits == 0)
return origRecoTrack;
337 for (
auto x : useInFit)
if (x) nHits++;
338 if (nHits < 5)
return lastRecoTrack;
345 const auto& recoHitInfos = recoTrack_copy->getRecoHitInformations(
true);
346 if (recoHitInfos.size() != useInFit.size()) {
347 B2ERROR(
"V0Fitter: copied recoTrack has different number of hits than the original one");
348 return lastRecoTrack;
350 for (
unsigned i = 0; i < recoHitInfos.size(); i++) recoHitInfos[i]->setUseInFit(useInFit[i]);
354 bool ok = fitter.
fit(*recoTrack_copy, ptype);
355 if (not ok)
return lastRecoTrack;
357 return recoTrack_copy;
364 ROOT::Math::XYZVector(state.getPos()),
365 ROOT::Math::XYZVector(state.getMom()),
367 state.get6DCov(), state.getTime());
377 std::vector<RecoHitInformation*> innerHitsPlus;
378 for (
const auto& hitInfo : recoHitInformationsPlus) {
379 if (hitInfo->useInFit()) innerHitsPlus.push_back(hitInfo);
380 if (innerHitsPlus.size() == 2)
break;
382 if (innerHitsPlus.empty())
return 0;
385 std::vector<RecoHitInformation*> innerHitsMinus;
386 for (
const auto& hitInfo : recoHitInformationsMinus) {
387 if (hitInfo->useInFit()) innerHitsMinus.push_back(hitInfo);
388 if (innerHitsMinus.size() == 2)
break;
390 if (innerHitsMinus.empty())
return 0;
392 if (innerHitsPlus.front()->getTrackingDetector() != innerHitsMinus.front()->getTrackingDetector())
return 0;
394 if (innerHitsPlus.front()->getTrackingDetector() == RecoHitInformation::c_PXD) {
395 const auto* clusterPlus = innerHitsPlus.front()->getRelatedTo<
PXDCluster>();
396 const auto* clusterMinus = innerHitsMinus.front()->getRelatedTo<
PXDCluster>();
397 if (clusterPlus and clusterPlus == clusterMinus)
return 0x03;
403 if (innerHitsPlus.front()->getTrackingDetector() == RecoHitInformation::c_SVD) {
404 const auto* clusterPlus = innerHitsPlus.front()->getRelatedTo<
SVDCluster>();
405 const auto* clusterMinus = innerHitsMinus.front()->getRelatedTo<
SVDCluster>();
406 if (clusterPlus and clusterPlus == clusterMinus) {
407 sensorID = clusterPlus->getSensorID();
408 if (clusterPlus->isUCluster()) flag = 0x01;
413 if (innerHitsPlus.size() != 2 or innerHitsMinus.size() != 2)
return flag;
415 if (innerHitsPlus.back()->getTrackingDetector() == RecoHitInformation::c_SVD) {
416 const auto* clusterPlus = innerHitsPlus.back()->getRelatedTo<
SVDCluster>();
417 const auto* clusterMinus = innerHitsMinus.back()->getRelatedTo<
SVDCluster>();
418 if (clusterPlus and clusterPlus == clusterMinus and clusterPlus->
getSensorID() == sensorID) {
419 if (clusterPlus->isUCluster()) flag |= 0x01;
433 B2ERROR(
"V0Fitter: bug in saving track fit result, recoTrack is nullptr");
439 if (sharedInnermostCluster > 0) {
441 pattern.setInnermostHitShareStatus(sharedInnermostCluster);
442 hitPatternVXD = pattern.getInteger();
445 const auto& state = trk.
state;
447 auto* fit =
m_trackFitResults.appendNew(ROOT::Math::XYZVector(state.getPos()), ROOT::Math::XYZVector(state.getMom()),
448 state.get6DCov(), state.getCharge(), trk.
ptype, trk.
pValue,
449 Bz, hitPatternCDC, hitPatternVXD, trk.
Ndf);
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
The ParticleType class for identifying different particle types.
int getPDGCode() const
PDG code.
static const ParticleType Lambda
Lambda particle.
static const ChargedStable pion
charged pion particle
static const ParticleType antiLambda
Anti-Lambda particle.
static const ChargedStable proton
proton particle
static const ParticleType invalidParticle
Invalid particle, used internally.
static const ParticleType Kshort
K^0_S particle.
static const ParticleType photon
photon particle
static const ChargedStable electron
electron particle
@ c_WriteOut
Object/array should be saved by output modules.
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Hit pattern of the VXD within a track.
StoreArray< V0ValidationVertex > m_validationV0s
V0ValidationVertex collection (optional)
StoreArray< RecoTrack > m_copiedRecoTracks
copied RecoTracks collection
FittedTrack m_trkPlus
positively charged track data of last successfully fitted vertex
bool m_validation
validation flag
StoreArray< V0 > m_v0s
V0s collection.
double m_vertexDistanceCut
cut on the transverse radius
double m_vertexChi2Cut
Chi2 cut.
StoreArray< TrackFitResult > m_trackFitResults
TrackFitResults collection.
bool fitAndStore(const Track *trackPlus, const Track *trackMinus, const Const::ParticleType &v0Hypothesis, bool &isForceStored, bool &isHitRemoved)
Fit V0 with given hypothesis and store results if fit is successful.
static int extrapolateToVertex(genfit::MeasuredStateOnPlane &statePlus, genfit::MeasuredStateOnPlane &stateMinus, const genfit::GFRaveVertex &vertex)
Extrapolation of both tracks to the vertex.
double m_momentum
momentum of last successfully fitted vertex
@ c_NoTrackRepresentation
no track representation for given PDG code
@ c_NotSelected
fitted vertex not passing the cuts
@ c_VertexFitFailed
vertex fit failed
@ c_ExtrapolationFailed
track extrapolation failed
static bool setCardinalRep(genfit::Track &gfTrack, int pdgCode)
Sets cardinal representation of a given genfit track and PDG code.
std::string m_recoTracksName
name of the RecoTracks collection
const TrackFitResult * saveTrackFitResult(const FittedTrack &trk, int sharedInnermostCluster)
Append track fit result to the collection.
int isInnermostClusterShared(const RecoTrack *recoTrackPlus, const RecoTrack *recoTrackMinus)
Returns bit flags indicating that the innermost cluster is shared between both tracks.
static const genfit::AbsTrackRep * getTrackRepresentation(const RecoTrack *recoTrack, int pdgCode)
Returns track representation for a given PDG code.
std::map< int, std::pair< double, double > > m_invMassCuts
invariant mass cuts, key = abs(PDG)
NewV0Fitter(const std::string &trackFitResultsName="", const std::string &v0sName="", const std::string &v0ValidationVerticesName="", const std::string &recoTracksName="", const std::string &copiedRecoTracksName="CopiedRecoTracks", bool enableValidation=false)
Constructor.
StoreArray< RecoTrack > m_recoTracks
RecoTracks collection.
genfit::GFRaveVertex m_fittedVertex
last successfully fitted vertex
static std::pair< Const::ParticleType, Const::ParticleType > getTrackHypotheses(const Const::ParticleType &v0Hypothesis)
Returns daughter particle types for a given V0 hypothesis.
std::unique_ptr< V0VertexFitter > m_vertexFitter
vertex fitter used to fit the V0 vertex
void initializeCuts(double vertexDistanceCut, double vertexChi2Cut, const std::tuple< double, double > &invMassRangeKshort, const std::tuple< double, double > &invMassRangeLambda, const std::tuple< double, double > &invMassRangePhoton)
Initialization of cuts applied during the fit and store process.
double m_invMass
invariant mass of last successfully fitted vertex
int m_fitterMode
fitter mode
FittedTrack m_trkMinus
negatively charged track data of last successfully fitted vertex
@ c_BitTrackMinus
negative track has inner hits
@ c_BitTrackPlus
positive track has inner hits
int vertexFit(const RecoTrack *recoTrackPlus, const RecoTrack *recoTrackMinus, int pdgTrackPlus, int pdgTrackMinus, const Const::ParticleType &v0Hypothesis)
Performs a vertex fit.
RecoTrack * copyRecoTrack(const RecoTrack *origRecoTrack, const genfit::MeasuredStateOnPlane &state)
Make a copy of reco track.
const RecoTrack * removeHitsAndRefit(const RecoTrack *origRecoTrack, const RecoTrack *lastRecoTrack, const Const::ParticleType &ptype)
Remove track inner hits and refit the track.
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
This is the Reconstruction Event-Data Model Track.
size_t addHitsFromRecoTrack(const RecoTrack *recoTrack, unsigned int sortingParameterOffset=0, bool reversed=false, std::optional< double > optionalMinimalWeight=std::nullopt)
Add all hits from another RecoTrack to this RecoTrack.
bool wasFitSuccessful(const genfit::AbsTrackRep *representation=nullptr) const
Returns true if the last fit with the given representation was successful.
RecoTrack * copyToStoreArrayUsing(StoreArray< RecoTrack > &storeArray, const ROOT::Math::XYZVector &position, const ROOT::Math::XYZVector &momentum, short charge, const TMatrixDSym &covariance, double timeSeed) const
Append a new RecoTrack to the given store array and copy its general properties, but not the hits the...
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
static void registerRequiredRelations(const StoreArray< RecoTrack > &recoTracks, std::string const &pxdHitsStoreArrayName="", std::string const &svdHitsStoreArrayName="", std::string const &cdcHitsStoreArrayName="", std::string const &bklmHitsStoreArrayName="", std::string const &eklmHitsStoreArrayName="", std::string const &recoHitInformationStoreArrayName="")
Convenience method which registers all relations required to fully use a 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...
genfit::AbsTrackRep * getTrackRepresentationForPDG(int pdgCode) const
Return an already created track representation of the given reco track for the PDG.
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromRecoHit(const RecoHitInformation *recoHitInfo, const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane on plane for associated with one RecoHitInformation.
const genfit::Track & getGenfitTrack() const
Returns genfit track.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
VxdID getSensorID() const
Get the sensor ID.
static uint32_t getHitPatternVXDInitializer(const RecoTrack &recoTrack, const genfit::AbsTrackRep *representation=nullptr)
Get the HitPattern in the VXD.
static uint64_t getHitPatternCDCInitializer(const RecoTrack &recoTrack, const genfit::AbsTrackRep *representation=nullptr)
Get the HitPattern in the CDC.
Values of the result of a track fit with a given particle hypothesis.
Const::ParticleType getParticleType() const
Getter for ParticleType of the mass hypothesis of the track fit.
Algorithm class to handle the fitting of RecoTrack objects.
bool fit(RecoTrack &recoTrack, genfit::AbsTrackRep *trackRepresentation, bool resortHits=false) const
Fit a reco track with a given non-default track representation.
Class that bundles various TrackFitResults.
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for the fit hypothesis with the closest mass.
Factory creating the V0VertexFitter selected at run time.
Class to uniquely identify a any structure of the PXD and SVD.
Abstract base class for different kinds of events.
Structure to save track data of the last successful iteration.
double pValue
p-value of track fit
genfit::MeasuredStateOnPlane state
measured state at first hit, extrapolated to fitted vertex
Const::ParticleType ptype
particle type of the V0 track
const RecoTrack * recoTrack
reco track
int Ndf
degrees-of-freedom of track fit