FastJet 3.0.0
|
00001 //STARTHEADER 00002 // $Id: TrackJetPlugin.cc 2577 2011-09-13 15:11:38Z salam $ 00003 // 00004 // Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez 00005 // 00006 //---------------------------------------------------------------------- 00007 // This file is part of FastJet. 00008 // 00009 // FastJet is free software; you can redistribute it and/or modify 00010 // it under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation; either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // The algorithms that underlie FastJet have required considerable 00015 // development and are described in hep-ph/0512210. If you use 00016 // FastJet as part of work towards a scientific publication, please 00017 // include a citation to the FastJet paper. 00018 // 00019 // FastJet is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 // GNU General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with FastJet. If not, see <http://www.gnu.org/licenses/>. 00026 //---------------------------------------------------------------------- 00027 //ENDHEADER 00028 00029 // fastjet stuff 00030 #include "fastjet/ClusterSequence.hh" 00031 #include "fastjet/TrackJetPlugin.hh" 00032 00033 // other stuff 00034 #include <list> 00035 #include <memory> 00036 #include <cmath> 00037 #include <vector> 00038 #include <sstream> 00039 00040 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00041 00042 using namespace std; 00043 00044 class TrackJetParticlePtr{ 00045 public: 00046 TrackJetParticlePtr(int i_index, double i_perp2) 00047 : index(i_index), perp2(i_perp2){} 00048 00049 int index; 00050 double perp2; 00051 00052 bool operator <(const TrackJetParticlePtr &other) const { 00053 return perp2>other.perp2; 00054 } 00055 }; 00056 00057 string TrackJetPlugin::description () const { 00058 ostringstream desc; 00059 desc << "TrackJet algorithm with R = " << R(); 00060 return desc.str(); 00061 } 00062 00063 void TrackJetPlugin::run_clustering(ClusterSequence & clust_seq) const { 00064 // we first need to sort the particles in pt 00065 vector<TrackJetParticlePtr> particle_list; 00066 00067 const vector<PseudoJet> & jets = clust_seq.jets(); 00068 int index=0; 00069 for (vector<PseudoJet>::const_iterator mom_it = jets.begin(); mom_it != jets.end(); mom_it++){ 00070 particle_list.push_back(TrackJetParticlePtr(index, mom_it->perp2())); 00071 index++; 00072 } 00073 00074 // sort the particles into decreasing pt 00075 stable_sort(particle_list.begin(), particle_list.end()); 00076 00077 00078 // if we're using a recombination scheme different from the E scheme, 00079 // we first need to update the particles' energy so that they 00080 // are massless (and rapidity = pseudorapidity) 00081 vector<PseudoJet> tuned_particles = clust_seq.jets(); 00082 vector<PseudoJet> tuned_tracks = clust_seq.jets(); 00083 for (vector<PseudoJet>::iterator pit = tuned_particles.begin(); 00084 pit != tuned_particles.end(); pit++) 00085 _jet_recombiner.preprocess(*pit); 00086 for (vector<PseudoJet>::iterator pit = tuned_tracks.begin(); 00087 pit != tuned_tracks.end(); pit++) 00088 _track_recombiner.preprocess(*pit); 00089 00090 00091 // we'll just need the particle indices for what follows 00092 list<int> sorted_pt_index; 00093 for (vector<TrackJetParticlePtr>::iterator mom_it = particle_list.begin(); 00094 mom_it != particle_list.end(); mom_it++) 00095 sorted_pt_index.push_back(mom_it->index); 00096 00097 // now start building the jets 00098 while (sorted_pt_index.size()){ 00099 // note that here 'track' refers to the direction we're using to test if a particle belongs to the jet 00100 // 'jet' refers to the momentum of the jet 00101 // the difference between the two is in the recombination scheme used to compute the sum of 4-vectors 00102 int current_jet_index = sorted_pt_index.front(); 00103 PseudoJet current_jet = tuned_particles[current_jet_index]; 00104 PseudoJet current_track = tuned_tracks[current_jet_index]; 00105 00106 // remove the first particle from the available ones 00107 list<int>::iterator index_it = sorted_pt_index.begin(); 00108 sorted_pt_index.erase(index_it); 00109 00110 // start browsing the remaining ones 00111 index_it = sorted_pt_index.begin(); 00112 while (index_it != sorted_pt_index.end()){ 00113 const PseudoJet & current_particle = tuned_particles[*index_it]; 00114 const PseudoJet & current_particle_track = tuned_tracks[*index_it]; 00115 00116 // check if the particle is within a distance R of the jet 00117 double distance2 = current_track.plain_distance(current_particle_track); 00118 if (distance2 <= _radius2){ 00119 // add the particle to the jet 00120 PseudoJet new_track; 00121 PseudoJet new_jet; 00122 _jet_recombiner.recombine(current_jet, current_particle, new_jet); 00123 _track_recombiner.recombine(current_track, current_particle_track, new_track); 00124 00125 int new_jet_index; 00126 clust_seq.plugin_record_ij_recombination(current_jet_index, *index_it, distance2, new_jet, new_jet_index); 00127 00128 current_jet = new_jet; 00129 current_track = new_track; 00130 current_jet_index = new_jet_index; 00131 00132 // particle has been clustered so remove it from the list 00133 sorted_pt_index.erase(index_it); 00134 00135 // and don't forget to start again from the beginning 00136 // as the jet axis may have changed 00137 index_it = sorted_pt_index.begin(); 00138 } else { 00139 index_it++; 00140 } 00141 } 00142 00143 // now we have a final jet, so cluster it with the beam 00144 clust_seq.plugin_record_iB_recombination(current_jet_index, _radius2); 00145 } 00146 00147 } 00148 00149 FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh