8#include <tracking/v0Finding/fitter/NewV0Fitter.h>
10#include <framework/logging/Logger.h>
11#include <framework/geometry/BFieldManager.h>
12#include <tracking/v0Finding/dataobjects/VertexVector.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/GFRaveVertexFactory.h>
20#include <genfit/FieldManager.h>
21#include <genfit/MaterialEffects.h>
23#include <framework/utilities/IOIntercept.h>
28 const std::string& v0ValidationVerticesName,
const std::string& recoTracksName,
29 const std::string& copiedRecoTracksName,
bool enableValidation)
30 : m_recoTracksName(recoTracksName), m_validation(enableValidation)
32 B2ASSERT(
"V0Fitter: material effects not set up. Please use SetupGenfitExtrapolationModule.",
33 genfit::MaterialEffects::getInstance()->isInitialized());
34 B2ASSERT(
"V0Fitter: magnetic field not set up. Please use SetupGenfitExtrapolationModule.",
35 genfit::FieldManager::getInstance()->isInitialized());
55 const std::tuple<double, double>& invMassRangeKshort,
56 const std::tuple<double, double>& invMassRangeLambda,
57 const std::tuple<double, double>& invMassRangePhoton)
61 m_invMassCuts[22] = std::make_pair(std::get<0>(invMassRangePhoton), std::get<1>(invMassRangePhoton));
62 m_invMassCuts[310] = std::make_pair(std::get<0>(invMassRangeKshort), std::get<1>(invMassRangeKshort));
63 m_invMassCuts[3122] = std::make_pair(std::get<0>(invMassRangeLambda), std::get<1>(invMassRangeLambda));
78 B2FATAL(
"V0Fitter: given V0 hypothesis not available.");
84 bool& isForceStored,
bool& isHitRemoved)
87 isForceStored =
false;
94 if (not recoTrackPlus)
return false;
96 if (not recoTrackMinus)
return false;
102 int pdgTrackPlus = std::abs(ptypeTrackPlus.getPDGCode());
103 int pdgTrackMinus = std::abs(ptypeTrackMinus.getPDGCode());
106 int status =
vertexFit(recoTrackPlus, recoTrackMinus, pdgTrackPlus, pdgTrackMinus, v0Hypothesis);
107 if (status < 0)
return false;
111 const RecoTrack* origRecoTrackPlus = recoTrackPlus;
112 const RecoTrack* origRecoTrackMinus = recoTrackMinus;
114 while (status != 0 and counter < 5) {
118 const RecoTrack* trkPlus = recoTrackPlus;
121 if (not trkPlus)
return false;
124 const RecoTrack* trkMinus = recoTrackMinus;
127 if (not trkMinus)
return false;
130 if (trkPlus == recoTrackPlus and trkMinus == recoTrackMinus)
break;
131 status =
vertexFit(trkPlus, trkMinus, pdgTrackPlus, pdgTrackMinus, v0Hypothesis);
132 if (status < 0)
break;
133 recoTrackPlus = trkPlus;
134 recoTrackMinus = trkMinus;
137 isForceStored = (status != 0);
143 if (not fitPlus)
return false;
145 if (not fitMinus)
return false;
147 auto* v0 =
m_v0s.appendNew(std::make_pair(trackPlus, fitPlus),
148 std::make_pair(trackMinus, fitMinus),
152 auto* validationV0 =
m_validationV0s.appendNew(std::make_pair(trackPlus, fitPlus),
153 std::make_pair(trackMinus, fitMinus),
158 v0->addRelationTo(validationV0);
187 genfit::GFRaveVertex vert;
189 auto vertexPos = ROOT::Math::XYZVector(vert.getPos());
198 const auto& p1 = vert.getParameters(0)->getMom();
199 const auto& p2 = vert.getParameters(1)->getMom();
201 double mass1 = trackHypotheses.first.getMass();
202 double mass2 = trackHypotheses.second.getMass();
203 ROOT::Math::PxPyPzMVector fourVec1(p1.X(), p1.Y(), p1.Z(), mass1);
204 ROOT::Math::PxPyPzMVector fourVec2(p2.X(), p2.Y(), p2.Z(), mass2);
205 double invMass = (fourVec1 + fourVec2).M();
208 if (invMass < cuts.first or invMass > cuts.second)
return c_NotSelected;
222 m_trkPlus.
set(recoTrackPlus, trackHypotheses.first, statePlus, plusRepresentation);
223 m_trkMinus.
set(recoTrackMinus, trackHypotheses.second, stateMinus, minusRepresentation);
234 B2ERROR(
"V0Fitter: track hypothesis with closest mass not available. Should never happen!");
241 const auto& reps = gfTrack.getTrackReps();
242 for (
unsigned id = 0;
id < reps.size();
id++) {
243 if (abs(reps[
id]->getPDG()) == pdgCode) {
244 gfTrack.setCardinalRep(
id);
249 B2ERROR(
"V0Fitter: cannot set cardinal representation for PDG = " << pdgCode);
257 std::vector<genfit::Track*> trackPair {&trackPlus, &trackMinus};
264 genfit::GFRaveVertexFactory vertexFactory;
265 vertexFactory.findVertices(&vertexVector.
v, trackPair);
267 B2ERROR(
"V0Fitter: exception during vertex fit.");
271 if (vertexVector.
size() != 1) {
272 B2DEBUG(21,
"Vertex fit failed. Size of vertexVector not 1, but: " << vertexVector.
size());
276 if ((*vertexVector[0]).getNTracks() != 2) {
277 B2DEBUG(20,
"Wrong number of tracks in vertex.");
281 vertex = *vertexVector[0];
287 const genfit::GFRaveVertex& vertex)
292 double extralengthPlus = statePlus.extrapolateToPoint(vertex.getPos());
293 double extralengthMinus = stateMinus.extrapolateToPoint(vertex.getPos());
302 B2DEBUG(22,
"Could not extrapolate track to vertex.");
312 std::vector<bool> useInFit;
314 useInFit.reserve(recoHitInformations.size());
315 for (
const auto& hitInfo : recoHitInformations) useInFit.push_back(hitInfo->useInFit());
319 if (not rep)
return lastRecoTrack;
323 unsigned firstHit = 0;
324 for (
unsigned i = 0; i < recoHitInformations.size(); i++) {
325 const auto& hitInfo = recoHitInformations[i];
326 if (not hitInfo->useInFit())
continue;
329 double extraLength = state.extrapolateToPoint(
m_fittedVertex.getPos());
330 if (extraLength > 0) {
337 }
catch (NoTrackFitResult()) {
338 B2WARNING(
"V0Fitter exception: no FitterInfo assigned for TrackPoint created from this RecoHit.");
346 B2DEBUG(22,
"Could not extrapolate track to vertex when removing inner hits.");
347 return lastRecoTrack;
353 std::vector<unsigned> svdIndex;
354 for (
unsigned i = 0; i < useInFit.size(); i++) {
355 if (not useInFit[i])
continue;
356 const auto& hitInfo = recoHitInformations[i];
357 if (hitInfo->getTrackingDetector() == RecoHitInformation::c_SVD) svdIndex.push_back(i);
360 if (not svdIndex.empty() and svdIndex.size() < 3) {
361 for (
unsigned i : svdIndex) {
368 if (removedHits == 0)
return origRecoTrack;
372 for (
auto x : useInFit)
if (x) nHits++;
373 if (nHits < 5)
return lastRecoTrack;
380 const auto& recoHitInfos = recoTrack_copy->getRecoHitInformations(
true);
381 if (recoHitInfos.size() != useInFit.size()) {
382 B2ERROR(
"V0Fitter: copied recoTrack has different number of hits than the original one");
383 return lastRecoTrack;
385 for (
unsigned i = 0; i < recoHitInfos.size(); i++) recoHitInfos[i]->setUseInFit(useInFit[i]);
389 bool ok = fitter.fit(*recoTrack_copy, ptype);
390 if (not ok)
return lastRecoTrack;
392 return recoTrack_copy;
399 ROOT::Math::XYZVector(state.getPos()),
400 ROOT::Math::XYZVector(state.getMom()),
402 state.get6DCov(), state.getTime());
412 std::vector<RecoHitInformation*> innerHitsPlus;
413 for (
const auto& hitInfo : recoHitInformationsPlus) {
414 if (hitInfo->useInFit()) innerHitsPlus.push_back(hitInfo);
415 if (innerHitsPlus.size() == 2)
break;
417 if (innerHitsPlus.empty())
return 0;
420 std::vector<RecoHitInformation*> innerHitsMinus;
421 for (
const auto& hitInfo : recoHitInformationsMinus) {
422 if (hitInfo->useInFit()) innerHitsMinus.push_back(hitInfo);
423 if (innerHitsMinus.size() == 2)
break;
425 if (innerHitsMinus.empty())
return 0;
427 if (innerHitsPlus.front()->getTrackingDetector() != innerHitsMinus.front()->getTrackingDetector())
return 0;
429 if (innerHitsPlus.front()->getTrackingDetector() == RecoHitInformation::c_PXD) {
430 const auto* clusterPlus = innerHitsPlus.front()->getRelatedTo<
PXDCluster>();
432 if (clusterPlus and clusterPlus == clusterMinus)
return 0x03;
438 if (innerHitsPlus.front()->getTrackingDetector() == RecoHitInformation::c_SVD) {
439 const auto* clusterPlus = innerHitsPlus.front()->getRelatedTo<
SVDCluster>();
441 if (clusterPlus and clusterPlus == clusterMinus) {
442 sensorID = clusterPlus->getSensorID();
443 if (clusterPlus->isUCluster()) flag = 0x01;
448 if (innerHitsPlus.size() != 2 or innerHitsMinus.size() != 2)
return flag;
450 if (innerHitsPlus.back()->getTrackingDetector() == RecoHitInformation::c_SVD) {
451 const auto* clusterPlus = innerHitsPlus.back()->getRelatedTo<
SVDCluster>();
453 if (clusterPlus and clusterPlus == clusterMinus and clusterPlus->
getSensorID() == sensorID) {
454 if (clusterPlus->isUCluster()) flag |= 0x01;
468 B2ERROR(
"V0Fitter: bug in saving track fit result, recoTrack is nullptr");
474 if (sharedInnermostCluster > 0) {
476 pattern.setInnermostHitShareStatus(sharedInnermostCluster);
477 hitPatternVXD = pattern.getInteger();
480 const auto& state = trk.
state;
482 auto* fit =
m_trackFitResults.appendNew(ROOT::Math::XYZVector(state.getPos()), ROOT::Math::XYZVector(state.getMom()),
483 state.get6DCov(), state.getCharge(), trk.
ptype, trk.
pValue,
484 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.
bool start()
Start intercepting the output.
Capture stdout and stderr and convert into log messages.
@ c_Debug
Debug: for code development.
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.
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
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.
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.
bool fitGFRaveVertex(genfit::Track &trackPlus, genfit::Track &trackMinus, genfit::GFRaveVertex &vertex)
Genfit Rave vertex fit called by vertexFit method.
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(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).
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
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.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
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.
Class that bundles various TrackFitResults.
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for a fit hypothesis with the closest mass.
Need this container for exception-safe cleanup, GFRave's interface isn't exception-safe as is.
std::vector< genfit::GFRaveVertex * > v
Fitted vertices.
size_t size() const noexcept
Return size of vertex vector.
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.
void set(const RecoTrack *recoTrk, const Const::ParticleType &hypo, const genfit::MeasuredStateOnPlane &mSoP, const genfit::AbsTrackRep *rep)
Sets the data members.
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