10 #include <analysis/modules/ParticleLoader/ParticleLoaderModule.h>
13 #include <framework/logging/Logger.h>
14 #include <framework/core/ModuleParam.templateDetails.h>
17 #include <analysis/DecayDescriptor/ParticleListName.h>
18 #include <analysis/utility/PCmsLabTransform.h>
43 setDescription(
"Loads MDST dataobjects as Particle objects to the StoreArray<Particle> and collects them in specified ParticleList.");
44 setPropertyFlags(c_ParallelProcessingCertified);
47 addParam(
"decayStrings", m_decayStrings,
48 "List of decay strings (see :ref:`DecayString` for syntax) that specify all output ParticleLists to be created by the module.",
51 addParam(
"useMCParticles", m_useMCParticles,
52 "Use MCParticles instead of reconstructed MDST dataobjects (tracks, ECL, KLM, clusters, V0s, ...)",
false);
54 addParam(
"useROEs", m_useROEs,
55 "Use ROE instead of reconstructed MDST dataobjects (tracks, ECL, KLM, clusters, V0s, ...)",
false);
57 addParam(
"roeMaskName", m_roeMaskName,
58 "ROE mask name to load", std::string(
""));
60 addParam(
"sourceParticleListName", m_sourceParticleListName,
61 "Particle list name from which we need to get ROEs", std::string(
""));
63 addParam(
"useMissing", m_useMissing,
64 "If true, the Particle List will be filled with missing momentum from the ROE and signal particle.",
false);
66 addParam(
"writeOut", m_writeOut,
67 "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.",
false);
69 addParam(
"addDaughters", m_addDaughters,
70 "If true, the particles from the bottom part of the selected particle's decay chain will also be created in the datastore and mother-daughter relations are recursively set",
73 addParam(
"skipNonPrimaryDaughters", m_skipNonPrimaryDaughters,
74 "If true, the secondary MC daughters will be skipped, default is false",
77 addParam(
"trackHypothesis", m_trackHypothesis,
78 "Track hypothesis to use when loading the particle. By default, use the particle's own hypothesis.",
81 addParam(
"enforceFitHypothesis", m_enforceFitHypothesis,
82 "If true, a Particle is only created if a track fit with the particle hypothesis passed to the ParticleLoader is available.",
83 m_enforceFitHypothesis);
86 void ParticleLoaderModule::initialize()
88 B2INFO(
"ParticleLoader's Summary of Actions:");
90 m_particles.registerInDataStore();
91 m_particleExtraInfoMap.registerInDataStore();
92 m_eventExtraInfo.registerInDataStore();
94 if (m_mcparticles.isOptional()) {
95 m_particles.registerRelationTo(m_mcparticles);
97 if (m_pidlikelihoods.isOptional()) {
98 m_particles.registerRelationTo(m_pidlikelihoods);
100 if (m_trackfitresults.isOptional()) {
101 m_particles.registerRelationTo(m_trackfitresults);
104 if (m_useMCParticles) {
105 m_mcparticles.isRequired();
108 if (m_decayStrings.empty()) {
109 B2WARNING(
"Obsolete usage of the ParticleLoader module (load all MDST objects as all possible Particle object types). Specify the particle type via decayStrings module parameter instead.");
111 for (
auto decayString : m_decayStrings) {
114 bool valid = m_decaydescriptor.init(decayString);
116 B2ERROR(
"ParticleLoaderModule::initialize Invalid input DecayString: " << decayString);
120 int nProducts = m_decaydescriptor.getNDaughters();
122 int pdgCode = mother->getPDGCode();
124 string listName = mother->getName() +
":all";
126 if (m_useROEs) listName = mother->getFullName();
128 else if (m_useMCParticles) listName = mother->getName() +
":MC";
130 else if (nProducts > 0) listName = mother->getName() +
":V0";
132 string antiListName = ParticleListName::antiParticleListName(listName);
133 bool isSelfConjugatedParticle = (listName == antiListName);
137 if (!particleList.isOptional()) {
139 particleList.registerInDataStore(flags);
140 if (!isSelfConjugatedParticle) {
146 if (not isValidPDGCode(pdgCode) and (m_useMCParticles ==
false and m_useROEs ==
false))
147 B2ERROR(
"Invalid particle type requested to be loaded. Set a valid decayString module parameter.");
150 bool mdstSourceIsV0 =
false;
151 if (!m_useMCParticles &&
152 (abs(pdgCode) == abs(Const::Kshort.getPDGCode()) || abs(pdgCode) == abs(Const::Lambda.getPDGCode())
153 || (abs(pdgCode) == abs(Const::photon.getPDGCode()) && m_addDaughters ==
true)))
154 mdstSourceIsV0 =
true;
156 if (mdstSourceIsV0 ==
false) {
159 B2ERROR(
"ParticleLoaderModule::initialize Invalid input DecayString " << decayString
160 <<
". DecayString should not contain any daughters, only the mother particle.");
162 B2INFO(
"ParticleLoaderModule: Replacing the source particle list name by " <<
163 m_decaydescriptor.getDaughter(0)->getMother()->getFullName()
164 <<
" all other daughters will be ignored.");
165 m_sourceParticleListName = m_decaydescriptor.getDaughter(0)->getMother()->getFullName();
170 B2ERROR(
"ParticleLoaderModule::initialize Invalid input DecayString " << decayString
171 <<
". MDST source of the particle list is V0, DecayString should contain exactly two daughters, as well as the mother particle.");
173 if (m_decaydescriptor.getDaughter(0)->getMother()->getPDGCode() * m_decaydescriptor.getDaughter(1)->getMother()->getPDGCode() > 0)
174 B2ERROR(
"MDST source of the particle list is V0, the two daughters should have opposite charge");
179 B2INFO(
" o) creating (anti-)ParticleList with name: " << listName <<
" (" << antiListName <<
")");
181 B2INFO(
" -> MDST source: RestOfEvents");
182 m_ROE2Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
183 }
else if (m_useMCParticles) {
184 B2INFO(
" -> MDST source: MCParticles");
185 m_MCParticles2Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
189 B2INFO(
" -> MDST source: Tracks");
190 m_Tracks2Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
193 if (abs(pdgCode) == abs(Const::photon.getPDGCode())) {
194 if (m_addDaughters ==
false) {
195 m_ECLKLMClusters2Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
196 B2INFO(
" -> MDST source: ECLClusters and KLMClusters");
198 B2INFO(
" -> MDST source: V0");
199 m_V02Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
203 if (abs(pdgCode) == abs(Const::Kshort.getPDGCode())) {
204 B2INFO(
" -> MDST source: V0");
205 m_V02Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
208 if (abs(pdgCode) == abs(Const::Klong.getPDGCode()) || abs(pdgCode) == abs(Const::neutron.getPDGCode())) {
209 B2INFO(
" -> MDST source: exclusively KLMClusters or exclusively ECLClusters (matching between those not used)");
210 m_ECLKLMClusters2Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
213 if (abs(pdgCode) == abs(Const::Lambda.getPDGCode())) {
214 B2INFO(
" -> MDST source: V0");
215 m_V02Plists.emplace_back(pdgCode, listName, antiListName, isSelfConjugatedParticle);
222 m_chargeZeroTrackCounts = std::vector<int>(m_Tracks2Plists.size(), 0);
223 m_sameChargeDaughtersV0Counts = std::vector<int>(m_V02Plists.size(), 0);
226 void ParticleLoaderModule::event()
228 if (not m_particleExtraInfoMap) {
229 m_particleExtraInfoMap.create();
234 else if (m_useMCParticles)
235 mcParticlesToParticles();
238 eclAndKLMClustersToParticles();
243 void ParticleLoaderModule::terminate()
246 for (
size_t i = 0; i < m_Tracks2Plists.size(); i++)
247 if (m_chargeZeroTrackCounts[i] > 0) {
248 auto track2Plist = m_Tracks2Plists[i];
249 B2WARNING(
"There were " << m_chargeZeroTrackCounts[i]
250 <<
" tracks skipped because of zero charge for "
251 << get<c_PListName>(track2Plist));
254 for (
size_t i = 0; i < m_V02Plists.size(); i++)
255 if (m_sameChargeDaughtersV0Counts[i] > 0) {
256 auto v02Plist = m_V02Plists[i];
257 B2WARNING(
"There were " << m_sameChargeDaughtersV0Counts[i]
258 <<
" v0s skipped because of same charge daughters for "
259 << get<c_PListName>(v02Plist));
263 void ParticleLoaderModule::roeToParticles()
265 if (m_ROE2Plists.empty())
268 auto roe2Plist = m_ROE2Plists[0];
269 string listName = get<c_PListName>(roe2Plist);
270 string antiListName = get<c_AntiPListName>(roe2Plist);
271 int pdgCode = get<c_PListPDGCode>(roe2Plist);
272 bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(roe2Plist);
280 plist->initialize(pdgCode, listName);
282 if (!isSelfConjugatedParticle) {
285 antiPlist->initialize(-1 * pdgCode, antiListName);
286 antiPlist->bindAntiParticleList(*(plist));
288 if (m_sourceParticleListName !=
"") {
292 B2FATAL(
"ParticleList " << m_sourceParticleListName <<
" could not be found or is not valid!");
293 for (
unsigned int i = 0; i < pList->getListSize(); i++) {
296 B2ERROR(
"ParticleList " << m_sourceParticleListName <<
" has no associated ROEs!");
298 addROEToParticleList(roe, i, pdgCode, isSelfConjugatedParticle);
304 for (
int i = 0; i < m_roes.getEntries(); i++) {
305 addROEToParticleList(m_roes[i], i);
310 void ParticleLoaderModule::addROEToParticleList(
RestOfEvent* roe,
int mdstIndex,
int pdgCode,
bool isSelfConjugatedParticle)
316 newPart = roe->
convertToParticle(m_roeMaskName, pdgCode, isSelfConjugatedParticle);
323 TLorentzVector signal4Vector = signalSideParticle->get4Vector();
324 TLorentzVector roe4Vector = roe->
get4Vector(m_roeMaskName);
325 TLorentzVector missing4Vector;
326 missing4Vector.SetVect(boost4Vector.Vect() - (signal4Vector.Vect() + roe4Vector.Vect()));
327 missing4Vector.SetE(missing4Vector.Vect().Mag());
328 auto isFlavored = (isSelfConjugatedParticle) ? Particle::EFlavorType::c_Unflavored : Particle::EFlavorType::c_Flavored;
329 newPart = m_particles.appendNew(missing4Vector, pdgCode, isFlavored, Particle::EParticleSourceObject::c_Undefined, mdstIndex);
332 for (
auto roe2Plist : m_ROE2Plists) {
333 string listName = get<c_PListName>(roe2Plist);
335 plist->addParticle(newPart);
340 void ParticleLoaderModule::v0sToParticles()
342 if (m_V02Plists.empty())
346 bool matchingDaughtersOrder =
true;
347 if (m_decaydescriptor.getDaughter(0)->getMother()->getPDGCode() < 0
348 && m_decaydescriptor.getDaughter(1)->getMother()->getPDGCode() > 0)
349 matchingDaughtersOrder =
false;
352 for (
size_t ilist = 0; ilist < m_V02Plists.size(); ilist++) {
353 auto v02Plist = m_V02Plists[ilist];
354 string listName = get<c_PListName>(v02Plist);
355 string antiListName = get<c_AntiPListName>(v02Plist);
356 int pdgCode = get<c_PListPDGCode>(v02Plist);
357 bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(v02Plist);
365 plist->initialize(pdgCode, listName);
367 if (!isSelfConjugatedParticle) {
370 antiPlist->initialize(-1 * pdgCode, antiListName);
372 antiPlist->bindAntiParticleList(*(plist));
376 for (
int i = 0; i < m_v0s.getEntries(); i++) {
377 const V0* v0 = m_v0s[i];
385 B2DEBUG(19,
"V0 with same charge daughters skipped!");
386 m_sameChargeDaughtersV0Counts[ilist]++;
394 if (v0Type.
getPDGCode() == Const::Kshort.getPDGCode()) {
395 pTypeP = Const::pion;
396 pTypeM = Const::pion;
397 }
else if (v0Type.
getPDGCode() == Const::Lambda.getPDGCode()) {
398 pTypeP = Const::proton;
399 pTypeM = Const::pion;
400 v0FlavorType = Particle::c_Flavored;
401 }
else if (v0Type.
getPDGCode() == Const::antiLambda.getPDGCode()) {
402 pTypeP = Const::pion;
403 pTypeM = Const::proton;
404 v0FlavorType = Particle::c_Flavored;
405 }
else if (v0Type.
getPDGCode() == Const::photon.getPDGCode()) {
406 pTypeP = Const::electron;
407 pTypeM = Const::electron;
409 B2WARNING(
"Unknown V0 hypothesis!");
415 bool correctOrder = matchingDaughtersOrder;
416 if (abs(v0Type.
getPDGCode()) == abs(m_decaydescriptor.getMother()->getPDGCode())
417 && v0Type.
getPDGCode() != m_decaydescriptor.getMother()->getPDGCode())
418 correctOrder = !correctOrder;
420 std::pair<Track*, Track*> v0Tracks = v0->
getTracks();
421 std::pair<TrackFitResult*, TrackFitResult*> v0TrackFitResults = v0->
getTrackFitResults();
423 Particle daugP((v0Tracks.first)->getArrayIndex(), v0TrackFitResults.first, pTypeP);
424 Particle daugM((v0Tracks.second)->getArrayIndex(), v0TrackFitResults.second, pTypeM);
426 const PIDLikelihood* pidP = (v0Tracks.first)->getRelated<PIDLikelihood>();
427 const PIDLikelihood* pidM = (v0Tracks.second)->getRelated<PIDLikelihood>();
429 const auto& mcParticlePWithWeight = (v0Tracks.first)->getRelatedToWithWeight<MCParticle>();
430 const auto& mcParticleMWithWeight = (v0Tracks.second)->getRelatedToWithWeight<MCParticle>();
437 newDaugP = m_particles.appendNew(daugP);
438 newDaugM = m_particles.appendNew(daugM);
440 newDaugM = m_particles.appendNew(daugM);
441 newDaugP = m_particles.appendNew(daugP);
447 if (mcParticlePWithWeight.first)
448 newDaugP->
addRelationTo(mcParticlePWithWeight.first, mcParticlePWithWeight.second);
453 if (mcParticleMWithWeight.first)
454 newDaugM->
addRelationTo(mcParticleMWithWeight.first, mcParticleMWithWeight.second);
473 Particle* newPart = m_particles.appendNew(v0P);
474 plist->addParticle(newPart);
479 void ParticleLoaderModule::tracksToParticles()
481 if (m_Tracks2Plists.empty())
485 for (
size_t ilist = 0; ilist < m_Tracks2Plists.size(); ilist++) {
486 auto track2Plist = m_Tracks2Plists[ilist];
487 string listName = get<c_PListName>(track2Plist);
488 string antiListName = get<c_AntiPListName>(track2Plist);
489 int pdgCode = get<c_PListPDGCode>(track2Plist);
490 bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(track2Plist);
498 plist->initialize(pdgCode, listName);
501 if (!isSelfConjugatedParticle) {
504 antiPlist->initialize(-1 * pdgCode, antiListName);
506 antiPlist->bindAntiParticleList(*(plist));
511 for (
int i = 0; i < m_tracks.getEntries(); i++) {
512 const Track* track = m_tracks[i];
514 const auto& mcParticleWithWeight = track->getRelatedToWithWeight<
MCParticle>();
517 if (m_trackHypothesis != 0) pdgCode = m_trackHypothesis;
522 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(type);
525 B2WARNING(
"Track returned null TrackFitResult pointer for ChargedStable::getPDGCode() = " << type.getPDGCode());
538 B2DEBUG(19,
"Track with charge = 0 skipped!");
539 m_chargeZeroTrackCounts[ilist]++;
544 Particle particle(track->getArrayIndex(), trackFit, type);
546 if (particle.getParticleSource() == Particle::c_Track) {
548 Particle* newPart = m_particles.appendNew(particle);
551 if (mcParticleWithWeight.first)
552 newPart->
addRelationTo(mcParticleWithWeight.first, mcParticleWithWeight.second);
555 plist->addParticle(newPart);
562 void ParticleLoaderModule::eclAndKLMClustersToParticles()
564 if (m_ECLKLMClusters2Plists.empty())
568 for (
auto eclKLMCluster2Plist : m_ECLKLMClusters2Plists) {
569 string listName = get<c_PListName>(eclKLMCluster2Plist);
570 string antiListName = get<c_AntiPListName>(eclKLMCluster2Plist);
571 int pdgCode = get<c_PListPDGCode>(eclKLMCluster2Plist);
572 bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(eclKLMCluster2Plist);
580 plist->initialize(pdgCode, listName);
583 if (!isSelfConjugatedParticle) {
586 antiPlist->initialize(-1 * pdgCode, antiListName);
588 antiPlist->bindAntiParticleList(*(plist));
592 for (
int i = 0; i < m_eclclusters.getEntries(); i++) {
598 if (!cluster->isNeutral())
continue;
599 if (not cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)
600 and not cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_neutralHadron))
608 std::vector<std::pair<int, double>> weightsAndIndices;
609 for (
unsigned int iMCParticle = 0; iMCParticle < mcRelations.
size(); iMCParticle++) {
610 const MCParticle* relMCParticle = mcRelations[iMCParticle];
611 double weight = mcRelations.
weight(iMCParticle);
613 weightsAndIndices.emplace_back(relMCParticle->
getArrayIndex(), weight);
616 std::sort(weightsAndIndices.begin(), weightsAndIndices.end(),
617 [](
const std::pair<int, double>& left,
const std::pair<int, double>& right) {
618 return left.second > right.second;
625 if (pdgCode == Const::photon.getPDGCode()
626 and not cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons))
631 if (pdgCode == Const::Klong.getPDGCode()
632 and not cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_neutralHadron))
637 if (abs(pdgCode) == Const::neutron.getPDGCode()
638 and not cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_neutralHadron))
642 Particle particle(cluster, thisType);
643 if (particle.getParticleSource() != Particle::c_ECLCluster) {
644 B2FATAL(
"Particle created from ECLCluster does not have ECLCluster type.");
647 Particle* newPart = m_particles.appendNew(particle);
650 for (
auto& weightsAndIndex : weightsAndIndices) {
651 const MCParticle* relMCParticle = m_mcparticles[weightsAndIndex.first];
652 double weight = weightsAndIndex.second;
659 && weight / relMCParticle->
getEnergy() > 0.30)
664 plist->addParticle(newPart);
668 for (
int i = 0; i < m_klmclusters.getEntries(); i++) {
671 if (std::isnan(cluster->getMomentumMag())) {
672 B2DEBUG(19,
"Skipping KLMCluster because its momentum is NaN. "
673 "This can happen if the timing calibration is missing or wrong, so that the velocity is calculated to be negative.");
680 Particle particle(cluster, pdgCode);
681 if (particle.getParticleSource() != Particle::c_KLMCluster) {
682 B2FATAL(
"Particle created from KLMCluster does not have KLMCluster type.");
684 Particle* newPart = m_particles.appendNew(particle);
690 plist->addParticle(newPart);
695 void ParticleLoaderModule::mcParticlesToParticles()
697 if (m_MCParticles2Plists.empty())
701 for (
auto mcParticle2Plist : m_MCParticles2Plists) {
702 string listName = get<c_PListName>(mcParticle2Plist);
703 string antiListName = get<c_AntiPListName>(mcParticle2Plist);
704 int pdgCode = get<c_PListPDGCode>(mcParticle2Plist);
705 bool isSelfConjugatedParticle = get<c_IsPListSelfConjugated>(mcParticle2Plist);
713 plist->initialize(pdgCode, listName);
715 if (!isSelfConjugatedParticle) {
718 antiPlist->initialize(-1 * pdgCode, antiListName);
720 antiPlist->bindAntiParticleList(*(plist));
723 for (
int i = 0; i < m_mcparticles.getEntries(); i++) {
724 const MCParticle* mcParticle = m_mcparticles[i];
726 if (abs(pdgCode) != abs(mcParticle->
getPDG()))
730 Particle* newPart = m_particles.appendNew(particle);
734 if (m_addDaughters) appendDaughtersRecursive(newPart);
736 plist->addParticle(newPart);
741 bool ParticleLoaderModule::isValidPDGCode(
const int pdgCode)
746 if (Const::chargedStableSet.find(abs(pdgCode)) != Const::invalidParticle)
749 if (abs(pdgCode) == abs(Const::photon.getPDGCode()))
752 if (abs(pdgCode) == abs(Const::Kshort.getPDGCode()))
755 if (abs(pdgCode) == abs(Const::Klong.getPDGCode()))
758 if (abs(pdgCode) == abs(Const::Lambda.getPDGCode()))
761 if (abs(pdgCode) == abs(Const::neutron.getPDGCode()))
767 void ParticleLoaderModule::appendDaughtersRecursive(
Particle* mother)
769 auto* mcmother = mother->getRelated<
MCParticle>();
774 vector<MCParticle*> mcdaughters = mcmother->
getDaughters();
776 for (
auto& mcdaughter : mcdaughters) {
777 if (!mcdaughter->hasStatus(MCParticle::c_PrimaryParticle) and m_skipNonPrimaryDaughters)
continue;
779 Particle* daughter = m_particles.appendNew(particle);
780 daughter->addRelationTo(mcdaughter);
781 mother->appendDaughter(daughter,
false);
783 if (mcdaughter->getNDaughters() > 0)
784 appendDaughtersRecursive(daughter);
Provides a type-safe way to pass members of the chargedStableSet set.
The ParticleType class for identifying different particle types.
int getPDGCode() const
PDG code.
EStoreFlags
Flags describing behaviours of objects etc.
Represents a particle in the DecayDescriptor.
A Class to store the Monte Carlo particle information.
float getEnergy() const
Return particle energy in GeV.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
int getPDG() const
Return PDG code of particle.
Class to collect log likelihoods from TOP, ARICH, dEdx, ECL and KLM aimed for output to mdst includes...
Loads MDST dataobjects as Particle objects to the StoreArray<Particle> and collects them in specified...
Class to store reconstructed particles.
TLorentzVector get4Vector() const
Returns Lorentz vector.
EFlavorType
describes flavor type, see getFlavorType().
double getECLClusterEnergy() const
Returns the energy of the ECLCluster for the particle.
void appendDaughter(const Particle *daughter, const bool updateType=true)
Appends index of daughter to daughters index array.
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
float weight(int index) const
Get weight with index.
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).
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
This is a general purpose class for collecting reconstructed MDST data objects that are not used in r...
TLorentzVector get4Vector(const std::string &maskName="") const
Get 4-momentum vector all (no mask) or a subset (use mask) of all Tracks and ECLClusters in ROE.
Particle * convertToParticle(const std::string &maskName="", int pdgCode=0, bool isSelfConjugated=true)
Converts ROE to Particle and adds it to StoreArray.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
Values of the result of a track fit with a given particle hypothesis.
short getChargeSign() const
Return track charge (1 or -1).
Const::ParticleType getParticleType() const
Getter for ParticleType of the mass hypothesis of the track fit.
Class that bundles various TrackFitResults.
Object holding information for V0s.
std::pair< TrackFitResult *, TrackFitResult * > getTrackFitResults() const
Get pair of the TrackFitResults, that are part of the V0 particle.
std::pair< Track *, Track * > getTracks() const
Get pair of yhe Tracks, that are part of the V0 particle.
Const::ParticleType getV0Hypothesis() const
Get the hypothesis under which the V0 particle was created.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.