9 #include <analysis/DecayDescriptor/DecayDescriptor.h> 
   10 #include <analysis/DecayDescriptor/DecayString.h> 
   11 #include <analysis/DecayDescriptor/DecayStringDecay.h> 
   12 #include <analysis/DecayDescriptor/DecayStringGrammar.h> 
   13 #include <analysis/utility/EvtPDLUtil.h> 
   14 #include <analysis/dataobjects/Particle.h> 
   16 #include <analysis/utility/AnalysisConfiguration.h> 
   18 #include <mdst/dataobjects/MCParticle.h> 
   20 #include <framework/gearbox/Const.h> 
   21 #include <framework/logging/Logger.h> 
   23 #include <TDatabasePDG.h> 
   25 #include <boost/variant/get.hpp> 
   26 #include <boost/spirit/include/qi.hpp> 
   51   std::string::const_iterator iter = str.begin();
 
   52   std::string::const_iterator end = str.end();
 
   53   bool r = phrase_parse(iter, end, g, boost::spirit::unicode::space, s);
 
   54   if (!r || iter != end) 
return false;
 
   67       B2WARNING(
"Could not initialise mother particle " << p->m_strName);
 
   71   } 
else if (
const DecayStringDecay* d = boost::get< DecayStringDecay > (&s)) {
 
   75       B2WARNING(
"Could not initialise mother particle " << d->m_mother.m_strName);
 
   80     if (d->m_strArrow == 
"->") {
 
   81       m_properties |= Particle::PropertyFlags::c_IsIgnoreRadiatedPhotons ;
 
   82       m_properties |= Particle::PropertyFlags::c_IsIgnoreIntermediate;
 
   83     } 
else if (d->m_strArrow == 
"=norad=>") {
 
   84       m_properties |= Particle::PropertyFlags::c_IsIgnoreIntermediate;
 
   85     } 
else if (d->m_strArrow == 
"=direct=>") {
 
   86       m_properties |= Particle::PropertyFlags::c_IsIgnoreRadiatedPhotons;
 
   87     } 
else if (d->m_strArrow == 
"=exact=>") {
 
   90       B2WARNING(
"Unknown arrow: " << d->m_strArrow);
 
   96     if (d->m_daughters.empty()) {
 
  100     int nDaughters = d->m_daughters.size();
 
  101     for (
int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
 
  103       m_isInitOK = daughter.init(d->m_daughters[iDaughter]);
 
  105         B2WARNING(
"Could not initialise daughter!");
 
  113     if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), 
"?nu")) !=  d->m_keywords.end()) {
 
  114       m_properties |= Particle::PropertyFlags::c_IsIgnoreNeutrino;
 
  117     if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), 
"?gamma")) != d->m_keywords.end()) {
 
  118       m_properties |= Particle::PropertyFlags::c_IsIgnoreGamma;
 
  121     if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), 
"...")) != d->m_keywords.end()) {
 
  122       m_properties |= Particle::PropertyFlags::c_IsIgnoreMassive;
 
  125     if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), 
"?addbrems")) != d->m_keywords.end()) {
 
  126       m_properties |= Particle::PropertyFlags::c_IsIgnoreBrems;
 
  143     B2WARNING(
"NULL pointer provided instead of particle.");
 
  148   if (
const auto* part_test = 
dynamic_cast<const Particle*
>(p))
 
  149     iPDGCode_p = part_test->getPDGCode();
 
  150   else if (
const auto* mc_test = 
dynamic_cast<const MCParticle*
>(p))
 
  151     iPDGCode_p = mc_test->getPDG();
 
  153     B2WARNING(
"Template type not supported!");
 
  157   int iPDGCodeCC_p = TDatabasePDG::Instance()->GetParticle(iPDGCode_p)->AntiParticle()->PdgCode();
 
  159   if (abs(iPDGCode_d) != abs(iPDGCode_p)) 
return 0;
 
  161   if (iPDGCode_p == iPDGCodeCC_p) iCC = 3;
 
  162   else if (iPDGCode_d == iPDGCode_p) iCC = 1;
 
  163   else if (iPDGCode_d == iPDGCodeCC_p) iCC = 2;
 
  165   const std::vector<T*> daughterList = p->getDaughters();
 
  166   int nDaughters_p = daughterList.size();
 
  176   if (nDaughters_p == 0) 
return 0;
 
  186   vector< pair< int, int > > singlematch;
 
  188   vector< pair< int, set<int> > > multimatch;
 
  190   bool isAmbiguities = 
false;
 
  192   set<int> matches_global;
 
  195   for (
int iDaughter_d = 0; iDaughter_d < 
getNDaughters(); iDaughter_d++) {
 
  197     for (
int jDaughter_p = 0; jDaughter_p < nDaughters_p; jDaughter_p++) {
 
  198       const T* daughter = daughterList[jDaughter_p];
 
  199       int iPDGCode_daughter_p = 0;
 
  200       if (
const auto* part_test = 
dynamic_cast<const Particle*
>(daughter))
 
  201         iPDGCode_daughter_p = part_test->getPDGCode();
 
  202       else if (
const auto* mc_test = 
dynamic_cast<const MCParticle*
>(daughter))
 
  203         iPDGCode_daughter_p = mc_test->getPDG();
 
  207         matches_global.insert(jDaughter_p);
 
  209       int iMatchResult = 
m_daughters[iDaughter_d].match(daughter, jDaughter_p);
 
  210       if (iMatchResult < 0) isAmbiguities = 
true;
 
  211       if (abs(iMatchResult) == 2 && iCC == 1) 
continue;
 
  212       if (abs(iMatchResult) == 1 && iCC == 2) 
continue;
 
  213       if (abs(iMatchResult) == 2 && iCC == 3) 
continue;
 
  214       matches.insert(jDaughter_p);
 
  215       matches_global.insert(jDaughter_p);
 
  217     if (matches.empty()) 
return 0;
 
  218     if (matches.size() == 1) {
 
  219       int jDaughter_p = *(matches.begin());
 
  220       singlematch.emplace_back(iDaughter_d, jDaughter_p);
 
  221     } 
else multimatch.emplace_back(iDaughter_d, matches);
 
  226       && 
int(matches_global.size()) != nDaughters_p) 
return 0;
 
  231   bool isModified = 
true;
 
  232   for (
int iTry = 0; iTry < 20; iTry++) {
 
  234     if (!isModified) 
break;
 
  236     for (
auto& itMulti : multimatch) {
 
  237       for (
auto& itSingle : singlematch) {
 
  239         if (itMulti.second.erase(itSingle.second)) {
 
  240           B2FATAL(
"Trying to execute part of the code with known bug, which is not fixed yet! Send email to anze.zupanc@ijs.si with notification that this happens!");
 
  267   if (!multimatch.empty()) isAmbiguities = 
true;
 
  268   if (isAmbiguities) 
return -iCC;
 
  286   vector<const Particle*> selparticles;
 
  290     if (motherPDG != decayDescriptorMotherPDG)
 
  291       B2ERROR(
"The PDG code of the mother particle (" << motherPDG <<
 
  292               ") does not match the PDG code of the DecayDescriptor mother (" << decayDescriptorMotherPDG <<
 
  293               ")! Check the order of the decay string is the same you expect in the reconstructed Particles.");
 
  294     selparticles.push_back(particle);
 
  297   for (
int iDaughter_d = 0; iDaughter_d < nDaughters_d; ++iDaughter_d) {
 
  299     int iDaughter_p = 
m_daughters[iDaughter_d].getMatchedDaughter();
 
  303     if (iDaughter_p < 0) iDaughter_p = iDaughter_d;
 
  306       B2WARNING(
"Could not find daughter!");
 
  310     int daughterPDG = abs(daughter->getPDGCode());
 
  312     if (daughterPDG != decayDescriptorDaughterPDG) {
 
  313       B2ERROR(
"The PDG code of the particle daughter (" << daughterPDG <<
 
  314               ") does not match the PDG code of the DecayDescriptor daughter (" << decayDescriptorDaughterPDG <<
 
  315               ")! Check the order of the decay string is the same you expect in the reconstructed Particles.");
 
  318     vector<const Particle*> seldaughters = 
m_daughters[iDaughter_d].getSelectionParticles(daughter);
 
  319     selparticles.insert(selparticles.end(), seldaughters.begin(), seldaughters.end());
 
  327   std::vector<int> decay, decaybar;
 
  330     int pdg = daughter->getPDGCode();
 
  331     decay.push_back(pdg);
 
  335   std::sort(decay.begin(), decay.end());
 
  336   std::sort(decaybar.begin(), decaybar.end());
 
  344   vector<string> strNames;
 
  347     vector<string> strDaughterNames = daughter.getSelectionNames();
 
  348     int nDaughters = strDaughterNames.size();
 
  349     for (
int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
 
  360     strNames.insert(strNames.end(), strDaughterNames.begin(), strDaughterNames.end());
 
  365   for (
auto itName = strNames.begin(); itName != strNames.end(); ++itName) {
 
  366     if (count(itName, strNames.end(), *itName) == 1) 
continue;
 
  368     string strNameOld = *itName;
 
  369     auto itOccurrence = strNames.begin();
 
  371     while (iOccurrence <= 10) {
 
  373       itOccurrence = find(itOccurrence, strNames.end(), strNameOld);
 
  375       if (itOccurrence == strNames.end()) 
break;
 
  377       string strNameNew = strNameOld + std::to_string(iOccurrence);
 
  379       if (count(strNames.begin(), strNames.end(), strNameNew) == 0) {
 
  380         *itOccurrence = strNameNew;
 
  385     if (iOccurrence == 10) {
 
  386       B2ERROR(
"DecayDescriptor::getSelectionNames - Something is wrong! More than 10x the same name!");
 
  398     vector<int> listPDGDaughters = daughter.getSelectionPDGCodes();
 
  399     listPDG.insert(listPDG.end(), listPDGDaughters.begin(), listPDGDaughters.end());
 
  408     std::vector<std::vector<std::pair<int, std::string>>> hierarchy = 
m_hierarchy;
 
  411   std::vector<std::pair<int, std::string>> currentPath;
 
  417   const std::vector<std::pair<int, std::string>>& currentPath)
 
  420   for (std::size_t i = 0; i < 
m_daughters.size(); i++) {
 
  421     std::vector<std::pair<int, std::string>> newPath = currentPath;
 
  423     std::vector<std::vector<std::pair<int, std::string>>> foundPathes = 
m_daughters[i].getHierarchyOfSelected(newPath);
 
  424     for (
auto& path : foundPathes) 
m_hierarchy.push_back(path);
 
  426   std::vector<std::vector<std::pair<int, std::string>>> hierarchy = 
m_hierarchy;
 
static AnalysisConfiguration * instance()
Returns a pointer to the singleton instance.
int getPDGCode() const
PDG code.
static const ParticleType photon
photon particle
Represents a particle in the DecayDescriptor.
int getPDGCode() const
Return PDG code.
std::string getNameSimple() const
Return the name from getName() without + - * or anti-.
bool init(const DecayStringParticle &p)
initialise member variables from std::string member variables contained in a DecayStringParticle stru...
bool isSelected() const
Is the particle selected in the decay string?
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
DecayDescriptor()
Default ctor.
bool isIgnoreBrems() const
Check if added Brems gammas shall be ignored.
bool isIgnoreRadiatedPhotons() const
Check if additional radiated photons shall be ignored.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
bool isSelfConjugated() const
Is the decay or the particle self conjugated.
const DecayDescriptorParticle * getMother() const
return mother.
DecayDescriptorParticle m_mother
Mother of the decay ('left side').
bool m_isInitOK
Is this object initialized correctly?
bool isIgnoreNeutrino() const
Check if missing neutrinos shall be ignored.
std::vector< int > getSelectionPDGCodes()
Return list of PDG codes of selected particles.
int getNDaughters() const
return number of direct daughters.
void resetMatch()
Reset results from previous call of the match() function.
bool isIgnoreMassive() const
Check if missing massive final state particles shall be ignored.
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
std::vector< std::vector< std::pair< int, std::string > > > getHierarchyOfSelected()
Function to get hierarchy of selected particles and their names (for python use)
bool isIgnoreGamma() const
Check if missing gammas shall be ignored.
static const DecayDescriptor & s_NULL
Singleton object representing NULL.
std::vector< std::string > getSelectionNames()
Return list of human readable names of selected particles.
std::vector< DecayDescriptor > m_daughters
Direct daughters of the decaying particle.
std::vector< std::vector< std::pair< int, std::string > > > m_hierarchy
Collection of hierarchy paths of selected particles.
std::vector< const Particle * > getSelectionParticles(const Particle *particle)
Get a vector of pointers with selected daughters in the decay tree.
int m_iDaughter_p
ID of the Daughter Particle* matched to this DecayDescriptor.
int match(const T *p, int iDaughter_p)
Internally called by match(Particle*) and match(MCParticle*) function.
bool isIgnoreIntermediate() const
Check if intermediate resonances/particles shall be ignored.
int m_properties
Particle property.
A Class to store the Monte Carlo particle information.
Class to store reconstructed particles.
int getPDGCode(void) const
Returns PDG code.
const Particle * getDaughter(unsigned i) const
Returns a pointer to the i-th daughter particle.
boost::variant< boost::recursive_wrapper< DecayStringDecay >, DecayStringParticle > DecayString
The DecayStringElement can be either a DecayStringDecay or a vector of mother particles.
bool hasAntiParticle(int pdgCode)
Checks if the particle with given pdg code has an anti-particle or not.
Abstract base class for different kinds of events.
Holds the information of a decay.
This class describes the grammar and the syntax elements of decay strings.
Holds the information of a particle in the decay string.