File indexing completed on 2025-08-06 08:17:44
0001
0002 #include "FastJetAlgoSub.h"
0003
0004 #include <jetbase/Jet.h>
0005 #include <jetbase/JetContainer.h>
0006
0007
0008 #include <fastjet/ClusterSequence.hh>
0009 #include <fastjet/JetDefinition.hh>
0010 #include <fastjet/PseudoJet.hh>
0011
0012
0013 #include <iostream>
0014 #include <sstream> // for basic_ostringstream
0015 #include <vector>
0016
0017 FastJetAlgoSub::FastJetAlgoSub(const FastJetOptions& options)
0018 : m_opt{options}
0019 {
0020 fastjet::ClusterSequence clusseq;
0021 if (m_opt.verbosity > 0)
0022 {
0023 fastjet::ClusterSequence::print_banner();
0024 }
0025 else
0026 {
0027 std::ostringstream nullstream;
0028 fastjet::ClusterSequence::set_fastjet_banner_stream(&nullstream);
0029 fastjet::ClusterSequence::print_banner();
0030 fastjet::ClusterSequence::set_fastjet_banner_stream(&std::cout);
0031 }
0032 }
0033
0034 void FastJetAlgoSub::identify(std::ostream& os)
0035 {
0036 os << " FastJetAlgoSub: ";
0037 if (m_opt.algo == Jet::ANTIKT)
0038 {
0039 os << "ANTIKT r=" << m_opt.jet_R;
0040 }
0041 else if (m_opt.algo == Jet::KT)
0042 {
0043 os << "KT r=" << m_opt.jet_R;
0044 }
0045 else if (m_opt.algo == Jet::CAMBRIDGE)
0046 {
0047 os << "CAMBRIDGE r=" << m_opt.jet_R;
0048 }
0049 os << std::endl;
0050 }
0051
0052
0053
0054
0055
0056 void FastJetAlgoSub::cluster_and_fill(std::vector<Jet*>& particles, JetContainer* jetcont)
0057 {
0058 if (m_opt.verbosity > 1)
0059 {
0060 std::cout << "FastJetAlgoSub::process_event -- entered" << std::endl;
0061 }
0062
0063
0064 std::vector<fastjet::PseudoJet> pseudojets;
0065 for (unsigned int ipart = 0; ipart < particles.size(); ++ipart)
0066 {
0067 float this_e = particles[ipart]->get_e();
0068
0069 if (this_e == 0.)
0070 {
0071 continue;
0072 }
0073
0074 float this_px = particles[ipart]->get_px();
0075 float this_py = particles[ipart]->get_py();
0076 float this_pz = particles[ipart]->get_pz();
0077
0078 if (this_e < 0)
0079 {
0080
0081 float e_ratio = 0.001 / this_e;
0082
0083 this_e = this_e * e_ratio;
0084 this_px = this_px * e_ratio;
0085 this_py = this_py * e_ratio;
0086 this_pz = this_pz * e_ratio;
0087
0088 if (m_opt.verbosity > 5)
0089 {
0090 std::cout << " FastJetAlgoSub input particle with negative-E, original kinematics px / py / pz / E = ";
0091 std::cout << particles[ipart]->get_px() << " / " << particles[ipart]->get_py() << " / " << particles[ipart]->get_pz() << " / " << particles[ipart]->get_e() << std::endl;
0092 std::cout << " --> entering with modified kinematics px / py / pz / E = " << this_px << " / " << this_py << " / " << this_pz << " / " << this_e << std::endl;
0093 }
0094 }
0095
0096 fastjet::PseudoJet pseudojet(this_px, this_py, this_pz, this_e);
0097
0098 pseudojet.set_user_index(ipart);
0099 pseudojets.push_back(pseudojet);
0100 }
0101
0102
0103 fastjet::JetDefinition* jetdef = nullptr;
0104 if (m_opt.algo == Jet::ANTIKT)
0105 {
0106 jetdef = new fastjet::JetDefinition(fastjet::antikt_algorithm, m_opt.jet_R, fastjet::E_scheme, fastjet::Best);
0107 }
0108 else if (m_opt.algo == Jet::KT)
0109 {
0110 jetdef = new fastjet::JetDefinition(fastjet::kt_algorithm, m_opt.jet_R, fastjet::E_scheme, fastjet::Best);
0111 }
0112 else if (m_opt.algo == Jet::CAMBRIDGE)
0113 {
0114 jetdef = new fastjet::JetDefinition(fastjet::cambridge_algorithm, m_opt.jet_R, fastjet::E_scheme, fastjet::Best);
0115 }
0116 else
0117 {
0118 return;
0119 }
0120
0121 fastjet::ClusterSequence jetFinder(pseudojets, *jetdef);
0122 std::vector<fastjet::PseudoJet> fastjets = jetFinder.inclusive_jets();
0123 delete jetdef;
0124
0125
0126 std::vector<Jet*> jets;
0127 for (unsigned int ijet = 0; ijet < fastjets.size(); ++ijet)
0128 {
0129 auto* jet = jetcont->add_jet();
0130
0131 if (m_opt.verbosity > 5 && fastjets[ijet].perp() > 15)
0132 {
0133 std::cout << " FastJetAlgoSub : jet # " << ijet << " comes out of clustering with pt / eta / phi = " << fastjets[ijet].perp() << " / " << fastjets[ijet].eta() << " / " << fastjets[ijet].phi();
0134 std::cout << ", px / py / pz / e = " << fastjets[ijet].px() << " / " << fastjets[ijet].py() << " / " << fastjets[ijet].pz() << " / " << fastjets[ijet].e() << std::endl;
0135 }
0136
0137 float total_px = 0;
0138 float total_py = 0;
0139 float total_pz = 0;
0140 float total_e = 0;
0141
0142
0143 std::vector<fastjet::PseudoJet> comps = fastjets[ijet].constituents();
0144 for (auto& comp : comps)
0145 {
0146 Jet* particle = particles[comp.user_index()];
0147
0148 total_px += particle->get_px();
0149 total_py += particle->get_py();
0150 total_pz += particle->get_pz();
0151 total_e += particle->get_e();
0152 jet->insert_comp(particle->get_comp_vec(), true);
0153 }
0154
0155 jet->set_comp_sort_flag();
0156
0157
0158 jet->set_px(total_px);
0159 jet->set_py(total_py);
0160 jet->set_pz(total_pz);
0161 jet->set_e(total_e);
0162 jet->set_id(ijet);
0163
0164 if (m_opt.verbosity > 5 && fastjets[ijet].perp() > 15)
0165 {
0166 std::cout << " FastJetAlgoSub : jet # " << ijet << " after correcting for proper constituent kinematics, pt / eta / phi = " << jet->get_pt() << " / " << jet->get_eta() << " / " << jet->get_phi();
0167 std::cout << ", px / py / pz / e = " << jet->get_px() << " / " << jet->get_py() << " / " << jet->get_pz() << " / " << jet->get_e() << std::endl;
0168 }
0169 }
0170
0171 if (m_opt.verbosity > 1)
0172 {
0173 std::cout << "FastJetAlgoSub::process_event -- exited" << std::endl;
0174 }
0175 return;
0176 }