File indexing completed on 2026-06-21 08:23:36
0001
0002
0003
0004 #ifndef __FJCONTRIB_FLAVINFO_HH__
0005 #define __FJCONTRIB_FLAVINFO_HH__
0006
0007 #ifdef __FJC_FLAVINFO_USEFJCORE__
0008 #define fastjet fjcore
0009 #include "fjcore_local.hh"
0010 #define FASTJET_BEGIN_NAMESPACE namespace fjcore {
0011 #define FASTJET_OVERRIDE override
0012 #define FASTJET_END_NAMESPACE }
0013 #else
0014 #include "fastjet/JetDefinition.hh"
0015
0016
0017
0018 #endif
0019
0020
0021 #include <iostream>
0022
0023
0024
0025 FASTJET_BEGIN_NAMESPACE
0026 namespace contrib{
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 class FlavInfo : public PseudoJet::UserInfoBase {
0038
0039 public:
0040
0041
0042
0043
0044
0045
0046 FlavInfo (int pdg_code = 0, int flags = 0);
0047
0048 FlavInfo (int n_d, int n_u, int n_s, int n_c, int n_b, int n_t, int flags = 0);
0049
0050
0051 void apply_modulo_2();
0052
0053
0054 void apply_any_abs();
0055
0056
0057
0058 int operator[](int iflv) const {return _flav_content[iflv];}
0059
0060
0061 void set_flav(int iflv, int n) {_flav_content[iflv] = n; update_flavourless_attribute();}
0062
0063
0064 bool operator==(const FlavInfo &) const;
0065 bool operator!=(const FlavInfo &) const;
0066
0067
0068
0069
0070
0071
0072 void reset_all_but_flav(int iflv);
0073
0074
0075
0076 int pdg_code() const {return _pdg_code;}
0077
0078
0079 void label_as_beam() {_flav_content[0] |= beam;}
0080
0081 bool is_beam() const {return (_flav_content[0] & beam);}
0082
0083
0084
0085
0086 void label_as_spectator() {_flav_content[0] |= spectator;}
0087
0088 bool is_spectator() const {return (_flav_content[0] & spectator);}
0089
0090
0091 bool is_flavourless() const {return (_flav_content[0] & _is_flavourless);}
0092 bool is_flavorless() const {return is_flavourless();}
0093
0094
0095 bool is_multiflavoured() const;
0096 bool is_multiflavored() const {return is_multiflavoured();}
0097
0098
0099
0100
0101
0102
0103
0104 bool has_opposite_flavour(const PseudoJet & particle) const;
0105 bool has_opposite_flavor(const PseudoJet & particle) const {return has_opposite_flavour(particle);}
0106
0107
0108 FlavInfo operator+(const FlavInfo &) const;
0109
0110 FlavInfo operator-(const FlavInfo &) const;
0111
0112
0113
0114 std::string description() const;
0115
0116
0117
0118 static const FlavInfo & flavour_of(const PseudoJet & particle);
0119
0120
0121
0122
0123
0124
0125 static const int beam = 2;
0126
0127
0128
0129
0130 static const int spectator = 4;
0131 int _flav_content[7];
0132 void update_flavourless_attribute();
0133 static const int _is_flavourless = 1;
0134 private:
0135 int _pdg_code;
0136 static const FlavInfo _no_flav;
0137
0138 };
0139
0140
0141
0142
0143 class FlavHistory : public PseudoJet::UserInfoBase {
0144 public:
0145
0146 FlavHistory(int initial_flavour_pdg_id) {
0147 _flavour_history.push_back(std::make_pair(-1, FlavInfo(initial_flavour_pdg_id)));
0148 }
0149
0150
0151 FlavHistory(const FlavInfo & initial_flavour) {
0152 _flavour_history.push_back(std::make_pair(-1, initial_flavour));
0153 }
0154
0155
0156 FlavHistory(const FlavInfo & initial_flavour,
0157 const int initial_hist_step) {
0158 _flavour_history.push_back(std::make_pair(initial_hist_step, initial_flavour));
0159 }
0160
0161
0162 const FlavInfo & current_flavour() const {return _flavour_history.back().second;}
0163
0164 const FlavInfo & initial_flavour() const {return _flavour_history.front().second;}
0165
0166
0167
0168 int current_hist_index() const {return _flavour_history.back().first;}
0169
0170
0171
0172 int initial_hist_index() const {return _flavour_history.front().first;}
0173
0174
0175
0176
0177
0178
0179 void apply_modulo_2() {
0180 for (unsigned i = 0; i < _flavour_history.size(); i++) {
0181 _flavour_history[i].second.apply_modulo_2();
0182 }
0183 }
0184
0185
0186 void label_as_beam() {
0187 _flavour_history.back().second.label_as_beam();
0188 }
0189
0190
0191 void update_flavour_history(FlavInfo new_flavour, int hist_step) {
0192 if (new_flavour != _flavour_history.back().second) {
0193 _flavour_history.push_back(std::make_pair(hist_step, new_flavour));
0194 }
0195 }
0196
0197
0198
0199
0200 void amend_last_history_index(int new_hist_step) {
0201 _flavour_history.back().first = new_hist_step;
0202 }
0203
0204
0205 const std::vector<std::pair<int, FlavInfo>> & history() const {return _flavour_history;}
0206
0207
0208
0209 static const FlavInfo & current_flavour_of(const PseudoJet & particle);
0210
0211
0212 static const int current_index_of(const PseudoJet &particle);
0213
0214
0215
0216 static const FlavInfo & initial_flavour_of(const PseudoJet &jet);
0217
0218
0219 static const int initial_index_of(const PseudoJet &jet) {
0220 if (jet.has_user_info<FlavHistory>()) {
0221 return jet.user_info<FlavHistory>().history()[0].first;
0222 } else {
0223 throw fastjet::Error(
0224 "A particle without FlavHistory was searched for FlavHistory.");
0225 }
0226 }
0227
0228
0229 const FlavInfo & flavour_at_step(int step) const {
0230 if (_flavour_history[0].first > step) {
0231 throw fastjet::Error(
0232 "A particle without FlavHistory was searched for FlavHistory.");
0233 }
0234 int index_needed = -1;
0235 for (unsigned i = 1; i < _flavour_history.size(); i++) {
0236 if ((_flavour_history[i].first > step) &&
0237 (_flavour_history[i - 1].first <= step))
0238 index_needed = i - 1;
0239 }
0240 if (index_needed == -1) {
0241 return _flavour_history.back().second;
0242 } else {
0243 return _flavour_history[index_needed].second;
0244 }
0245 }
0246
0247
0248
0249
0250 void reset_flavour_history() {
0251 std::pair<int, FlavInfo> orig_flavour = _flavour_history[0];
0252 std::vector<std::pair<int, FlavInfo>> _new_history;
0253 _new_history.push_back(orig_flavour);
0254 _flavour_history = _new_history;
0255 }
0256 const std::vector<std::pair<int, FlavInfo>> & history() {return _flavour_history;}
0257
0258
0259 static const FlavInfo & current_flavor_of(const PseudoJet & particle) {return current_flavour_of(particle);}
0260 static const FlavInfo & initial_flavor_of(const PseudoJet & particle) {return initial_flavour_of(particle);}
0261 const FlavInfo & flavor_at_step(int step) const {return flavour_at_step(step);}
0262 const FlavInfo & current_flavor() const {return current_flavour();}
0263 const FlavInfo & initial_flavor() const {return initial_flavour();}
0264
0265
0266 private:
0267 std::vector<std::pair<int, FlavInfo>> _flavour_history;
0268 };
0269
0270
0271
0272 class FlavRecombiner : public JetDefinition::DefaultRecombiner {
0273 public:
0274
0275 enum FlavSummation {
0276
0277
0278
0279
0280
0281 net,
0282
0283
0284
0285
0286
0287
0288 modulo_2,
0289
0290
0291
0292
0293
0294
0295
0296 any_abs
0297 };
0298
0299
0300 FlavRecombiner(FlavSummation flav_summation_in = net) :
0301 DefaultRecombiner(), _flav_summation(flav_summation_in) {
0302
0303 }
0304
0305
0306 FlavSummation flav_summation() const {return _flav_summation;}
0307
0308 void preprocess(PseudoJet & p) const FASTJET_OVERRIDE {
0309
0310 FlavInfo flav;
0311 if (p.has_user_info<FlavInfo>()) {
0312 flav = p.user_info<FlavInfo>();
0313 } else if (p.has_user_info<FlavHistory>()) {
0314
0315
0316
0317 flav = p.user_info<FlavHistory>().initial_flavour();
0318 } else {
0319 throw Error("Could not identify FlavInfo or FlavHistory");
0320 }
0321
0322
0323 apply_summation_choice(flav);
0324 p.set_user_info(new FlavHistory(flav));
0325 }
0326
0327
0328 void recombine(const PseudoJet &pa,
0329 const PseudoJet &pb,
0330 PseudoJet &pab) const FASTJET_OVERRIDE {
0331
0332
0333 DefaultRecombiner::recombine(pa, pb, pab);
0334
0335
0336 assert(!pab.has_user_info<FlavHistory>());
0337
0338
0339
0340 FlavInfo flav = FlavHistory::current_flavour_of(pa) + FlavHistory::current_flavour_of(pb);
0341
0342
0343 apply_summation_choice(flav);
0344
0345
0346 pab.set_user_info(new FlavHistory(flav,pab.cluster_hist_index()));
0347
0348 }
0349
0350
0351 void apply_summation_choice(FlavInfo & flav) const {
0352
0353 if (_flav_summation == modulo_2) flav.apply_modulo_2();
0354 else if (_flav_summation == any_abs) flav.apply_any_abs();
0355 else if (_flav_summation != net) throw Error("FlavRecombiner: unknown FlavSummation");
0356 }
0357
0358
0359 std::string description() const FASTJET_OVERRIDE { return DefaultRecombiner::description() + " and " + to_string(_flav_summation) + " flavour recombination "; }
0360
0361 std::string to_string(FlavSummation flav_summation) const {
0362 return (flav_summation == net ? "net_flav" :
0363 flav_summation == modulo_2 ? "mod2_flav" :
0364 flav_summation == any_abs ? "any_flav" : "unknown");
0365 }
0366
0367 private:
0368 FlavSummation _flav_summation;
0369
0370 };
0371
0372
0373 }
0374 FASTJET_END_NAMESPACE
0375 #endif