00001
00002 #include "Rivet/Rivet.hh"
00003 #include "Rivet/Tools/Logging.hh"
00004 #include "Rivet/Projections/FastJets.hh"
00005
00006 namespace Rivet {
00007
00008
00009 FastJets::FastJets(const FinalState& fsp, JetAlgName alg, double rparameter, double seed_threshold)
00010 : JetAlg(fsp), _adef(0)
00011 {
00012 _init1(alg, rparameter, seed_threshold);
00013 }
00014
00015 FastJets::FastJets(const FinalState& fsp, fastjet::JetAlgorithm type,
00016 fastjet::RecombinationScheme recom, double rparameter)
00017 : JetAlg(fsp), _adef(0)
00018 {
00019 _init2(type, recom, rparameter);
00020 }
00021
00022
00023 FastJets::FastJets(const FinalState& fsp,
00024 fastjet::JetDefinition::Plugin& plugin)
00025 : JetAlg(fsp), _adef(0)
00026 {
00027 _init3(plugin);
00028 }
00029
00030
00031 FastJets::FastJets(JetAlgName alg, double rparameter, double seed_threshold)
00032 : _adef(0)
00033 {
00034 _init1(alg, rparameter, seed_threshold);
00035 }
00036
00037 FastJets::FastJets(fastjet::JetAlgorithm type,
00038 fastjet::RecombinationScheme recom, double rparameter)
00039 : _adef(0)
00040 {
00041 _init2(type, recom, rparameter);
00042 }
00043
00044
00045 FastJets::FastJets(fastjet::JetDefinition::Plugin& plugin)
00046 : _adef(0)
00047 {
00048 _init3(plugin);
00049 }
00050
00051
00052 int FastJets::compare(const Projection& p) const {
00053 const FastJets& other = dynamic_cast<const FastJets&>(p);
00054
00055 return \
00056 (_useInvisibles ? mkNamedPCmp(other, "FS") : mkNamedPCmp(other, "VFS")) ||
00057 cmp(_jdef.jet_algorithm(), other._jdef.jet_algorithm()) ||
00058 cmp(_jdef.recombination_scheme(), other._jdef.recombination_scheme()) ||
00059 cmp(_jdef.plugin(), other._jdef.plugin()) ||
00060 cmp(_jdef.R(), other._jdef.R()) ||
00061 cmp(_adef, other._adef);
00062 }
00063
00064
00065
00066 void FastJets::project(const Event& e) {
00067 ParticleVector particles;
00068 if (_useInvisibles) {
00069 particles = applyProjection<FinalState>(e, "FS").particles();
00070 } else {
00071 particles = applyProjection<FinalState>(e, "VFS").particles();
00072 }
00073 calc(particles);
00074 }
00075
00076
00077 void FastJets::calc(const ParticleVector& ps) {
00078 _particles.clear();
00079 vector<fastjet::PseudoJet> vecs;
00080
00081 int counter = 1;
00082 foreach (const Particle& p, ps) {
00083 const FourMomentum fv = p.momentum();
00084 fastjet::PseudoJet pJet(fv.px(), fv.py(), fv.pz(), fv.E());
00085 pJet.set_user_index(counter);
00086 vecs.push_back(pJet);
00087 _particles[counter] = p;
00088 ++counter;
00089 }
00090 MSG_DEBUG("Running FastJet ClusterSequence construction");
00091
00092
00093 if (_adef == 0) {
00094 _cseq.reset(new fastjet::ClusterSequence(vecs, _jdef));
00095 } else {
00096 _cseq.reset(new fastjet::ClusterSequenceArea(vecs, _jdef, *_adef));
00097 }
00098 }
00099
00100
00101 Jets FastJets::_pseudojetsToJets(const PseudoJets& pjets) const {
00102 Jets rtn;
00103 foreach (const fastjet::PseudoJet& pj, pjets) {
00104 Jet j;
00105 assert(clusterSeq());
00106 const PseudoJets parts = clusterSeq()->constituents(pj);
00107 foreach (const fastjet::PseudoJet& p, parts) {
00108 map<int, Particle>::const_iterator found = _particles.find(p.user_index());
00109 assert(found != _particles.end());
00110 j.addParticle(found->second);
00111 }
00112 rtn.push_back(j);
00113 }
00114 return rtn;
00115 }
00116
00117
00118 void FastJets::reset() {
00119 _yscales.clear();
00120 _particles.clear();
00121
00122 }
00123
00124
00125 size_t FastJets::numJets(double ptmin) const {
00126 if (_cseq.get() != 0) {
00127 return _cseq->inclusive_jets(ptmin).size();
00128 } else {
00129 return 0;
00130 }
00131 }
00132
00133
00134 Jets FastJets::_jets(double ptmin) const {
00135 Jets rtn = _pseudojetsToJets(pseudoJets(ptmin));
00136 return rtn;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 PseudoJets FastJets::pseudoJets(double ptmin) const {
00156 if (_cseq.get() != 0) {
00157 return _cseq->inclusive_jets(ptmin);
00158 } else {
00159 return PseudoJets();
00160 }
00161 }
00162
00163
00164 vector<double> FastJets::ySubJet(const fastjet::PseudoJet& jet) const {
00165 assert(clusterSeq());
00166 fastjet::ClusterSequence subjet_cseq(clusterSeq()->constituents(jet), _jdef);
00167 vector<double> yMergeVals;
00168 for (int i = 1; i < 4; ++i) {
00169
00170
00171 const double ktmerge = subjet_cseq.exclusive_dmerge(i) * _jdef.R()*_jdef.R();
00172 yMergeVals.push_back(ktmerge/jet.perp2());
00173 }
00174 _yscales.insert(make_pair( jet.cluster_hist_index(), yMergeVals ));
00175 return yMergeVals;
00176 }
00177
00178
00179
00180 fastjet::PseudoJet FastJets::splitJet(fastjet::PseudoJet jet, double& last_R) const {
00181
00182 if (jet.E() <= 0 || _cseq->constituents(jet).size() <= 1) {
00183 return jet;
00184 }
00185
00186
00187 assert(clusterSeq());
00188 fastjet::ClusterSequence cs(clusterSeq()->constituents(jet), _jdef);
00189
00190
00191 fastjet::PseudoJet remadeJet = cs.inclusive_jets()[0];
00192 MSG_DEBUG("Jet2:" << remadeJet.m() << "," << remadeJet.e());
00193
00194 fastjet::PseudoJet parent1, parent2;
00195 fastjet::PseudoJet split(0.0, 0.0, 0.0, 0.0);
00196 while (cs.has_parents(remadeJet, parent1, parent2)) {
00197 MSG_DEBUG("Parents:" << parent1.m() << "," << parent2.m());
00198 if (parent1.m2() < parent2.m2()) {
00199 fastjet::PseudoJet tmp;
00200 tmp = parent1; parent1 = parent2; parent2 = tmp;
00201 }
00202
00203 double ktdist = parent1.kt_distance(parent2);
00204 double rtycut2 = 0.3*0.3;
00205 if (parent1.m() < ((2.0*remadeJet.m())/3.0) && ktdist > rtycut2*remadeJet.m2()) {
00206 break;
00207 } else {
00208 remadeJet = parent1;
00209 }
00210 }
00211
00212 last_R = 0.5 * sqrt(parent1.squared_distance(parent2));
00213 split.reset(remadeJet.px(), remadeJet.py(), remadeJet.pz(), remadeJet.E());
00214 return split;
00215 }
00216
00217
00218
00219 fastjet::PseudoJet FastJets::filterJet(fastjet::PseudoJet jet,
00220 double& stingy_R, const double def_R) const {
00221 assert(clusterSeq());
00222
00223 if (jet.E() <= 0.0 || clusterSeq()->constituents(jet).size() == 0) {
00224 return jet;
00225 }
00226 if (stingy_R == 0.0) {
00227 stingy_R = def_R;
00228 }
00229
00230 stingy_R = def_R < stingy_R ? def_R : stingy_R;
00231 fastjet::JetDefinition stingy_jet_def(fastjet::cambridge_algorithm, stingy_R);
00232
00233
00234
00235 fastjet::ClusterSequence scs(clusterSeq()->constituents(jet), stingy_jet_def);
00236 std::vector<fastjet::PseudoJet> stingy_jets = sorted_by_pt(scs.inclusive_jets());
00237
00238 fastjet::PseudoJet reconst_jet(0.0, 0.0, 0.0, 0.0);
00239
00240 for (unsigned isj = 0; isj < std::min(3U, (unsigned int) stingy_jets.size()); ++isj) {
00241 reconst_jet += stingy_jets[isj];
00242 }
00243 return reconst_jet;
00244 }
00245
00246 }