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 == 
"->") {
 
   83    } 
else if (d->m_strArrow == 
"=norad=>") {
 
   85    } 
else if (d->m_strArrow == 
"=direct=>") {
 
   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()) {
 
  117    if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), 
"?gamma")) != d->m_keywords.end()) {
 
  121    if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), 
"...")) != d->m_keywords.end()) {
 
  125    if ((std::find(d->m_keywords.begin(), d->m_keywords.end(), 
"?addbrems")) != d->m_keywords.end()) {
 
  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;
 
  288    int motherPDG = abs(particle->getPDGCode());
 
  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;
 
  304    const Particle* daughter = particle->getDaughter(iDaughter_p);
 
  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 DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
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.
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.
const DecayDescriptorParticle * getMother() const
return mother.
int m_properties
Particle property.
A Class to store the Monte Carlo particle information.
Class to store reconstructed particles.
@ c_IsIgnoreNeutrino
Is the particle MC matched with the ignore missing neutrino flag set?
@ c_IsIgnoreRadiatedPhotons
Is the particle MC matched with the ignore radiated photon flag set?
@ c_IsIgnoreGamma
Is the particle MC matched with the ignore missing gamma flag set?
@ c_IsIgnoreBrems
Is the particle MC matched with the ignore added Brems gamma flag set?
@ c_IsIgnoreIntermediate
Is the particle MC matched with the ignore intermediate resonances flag set?
@ c_IsIgnoreMassive
Is the particle MC matched with the ignore missing massive particle flag set?
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.