// Copyright (c) 2023, Fabrizio Caola, Radoslaw Grabarczyk, // Maxwell Hutt, Gavin P. Salam, Ludovic Scyboz, and Jesse Thaler #include "fastjet/contrib/FlavInfo.hh" #include #ifndef __FJC_FLAVINFO_USEFJCORE__ #include "fastjet/ClusterSequence.hh" #include "fastjet/SharedPtr.hh" #endif using namespace std; FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh namespace contrib{ //---------------------------------------------------------------------- FlavInfo::FlavInfo(int n_d, int n_u, int n_s, int n_c, int n_b, int n_t, int flags) : _pdg_code(0) { _flav_content[0] = flags; _flav_content[1] = n_d; _flav_content[2] = n_u; _flav_content[3] = n_s; _flav_content[4] = n_c; _flav_content[5] = n_b; _flav_content[6] = n_t; update_flavourless_attribute(); } //---------------------------------------------------------------------- FlavInfo::FlavInfo(int pdg_code, int flags) : _pdg_code(pdg_code){ _flav_content[0] = flags; for(unsigned i = 1; i <= 6; i++) _flav_content[i] = 0; // for particles with illicit (zero) pdg_code, no work to be done if (_pdg_code == 0) return; int netsign = (pdg_code >= 0 ? +1 : -1); pdg_code = abs(pdg_code); // extract digits of the pdg_code, since these contain information // on flavour of component quarks valarray digit(4); int ndigits = 0; for (int i = 0; i < 4; i++) { digit[i] = pdg_code % 10; if (digit[i] != 0) ndigits = i+1; pdg_code /= 10; // "shift" things along } // start this part with _flav_content already initialised to zero // in constructor if (ndigits == 1) { // a lone quark if (digit[0] > 6 || digit[0] == 0) { cerr << "FlavInfo failed to understand pdg_code = "<<_pdg_code< 6) {cerr << "FlavInfo failed to understand pdg_code = " <<_pdg_code< 0) _flav_content[digit[i]] += netsign;} } else if (ndigits == 3) { // meson [nmx] // Beware of PDG convention that says that a K+ or B+ are a // particle and so have positive pdg_code (i.e. flavcodes > 1). So if (digit[2] == 3 || digit[2] == 5) netsign = -netsign; _flav_content[digit[2]] += netsign; _flav_content[digit[1]] -= netsign; } else { cerr << "FlavInfo failed to understand pdg_code = " <<_pdg_code< 1; } bool FlavInfo::has_opposite_flavour(const PseudoJet & particle) const { int t = 0; for(int i = 1; i<=6; i++){ if((particle.has_user_info()) && ((particle.user_info().operator[](i)*operator[](i) < -0))){ t += 1; } } return t > 0; } //---------------------------------------------------------------------- // an object with no flavour, that we can conveniently point to const FlavInfo FlavInfo::_no_flav; //---------------------------------------------------------------------- string FlavInfo::description() const { const char * flavs = "duscbt"; ostringstream result; result << "["; if (is_flavourless()) { result << "g"; } else { for (int iflav = 1; iflav <= 6; iflav++) { int n = operator[](iflav); for (unsigned i = 0; i < abs(n); i++) { result << flavs[iflav-1]; if (n<0) result << "bar"; result << " "; } } } result << "]"; if (is_beam()) result << "(beam) "; if (is_spectator()) result << "(spectator) "; return result.str(); } /// returns the flavour of a particle if that particle has flavour, otherwise /// just the default flavour const FlavInfo & FlavInfo::flavour_of(const PseudoJet & particle) { if (particle.has_user_info()) { return particle.user_info(); } else if (particle.has_user_info()) { throw Error("FlavInfo::flavour_of called on particle with FlavHistory. " "Use FlavHistory::current_flavour_of(...) or " "FlavHistory::initial_flavour_of(...) instead"); } else { return _no_flav; } } /// Return the current (final) flavour element of the history of a PseudoJet const FlavInfo & FlavHistory::current_flavour_of(const PseudoJet & particle) { if (particle.has_user_info()) { return particle.user_info().history().back().second; } else if (particle.has_user_info()) { return particle.user_info(); } else { throw fastjet::Error("A particle without FlavHistory was searched for FlavHistory."); } } /// Return the first flavour element of the history of a PseudoJet const FlavInfo & FlavHistory::initial_flavour_of(const PseudoJet &jet) { if (jet.has_user_info()) { return jet.user_info().history()[0].second; } else if (jet.has_user_info()) { return jet.user_info(); } else { throw fastjet::Error( "A particle without FlavHistory was searched for FlavHistory."); } } //---------------------------------------------------------------------- } // namespace contrib FASTJET_END_NAMESPACE