FastJet 3.0beta1
|
00001 //STARTHEADER 00002 // $Id: ClusterSequenceActiveAreaExplicitGhosts.cc 2269 2011-06-21 12:37:08Z salam $ 00003 // 00004 // Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam 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, write to the Free Software 00026 // Foundation, Inc.: 00027 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00028 //---------------------------------------------------------------------- 00029 //ENDHEADER 00030 00031 #include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh" 00032 #include<limits> 00033 00034 using namespace std; 00035 00036 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00037 00038 // save some typing 00039 typedef ClusterSequenceActiveAreaExplicitGhosts ClustSeqActAreaEG; 00040 00041 00042 LimitedWarning ClustSeqActAreaEG::_warnings; 00043 00044 //---------------------------------------------------------------------- 00045 /// 00046 void ClustSeqActAreaEG::_add_ghosts ( 00047 const GhostedAreaSpec & ghost_spec) { 00048 00049 // add the ghosts to the jets 00050 ghost_spec.add_ghosts(_jets); 00051 00052 // now add labelling... 00053 for (unsigned i = _initial_hard_n; i < _jets.size(); i++) { 00054 //_jets[i].set_user_index(1); 00055 _is_pure_ghost.push_back(true); 00056 } 00057 00058 // and record some info from the ghost_spec 00059 _ghost_area = ghost_spec.actual_ghost_area(); 00060 _n_ghosts = ghost_spec.n_ghosts(); 00061 } 00062 00063 00064 //---------------------------------------------------------------------- 00065 // return the area of a jet 00066 double ClustSeqActAreaEG::area (const PseudoJet & jet) const { 00067 return _areas[jet.cluster_hist_index()]; 00068 } 00069 00070 00071 //---------------------------------------------------------------------- 00072 // return the total area 00073 double ClustSeqActAreaEG::total_area () const { 00074 return _n_ghosts * _ghost_area; 00075 } 00076 00077 00078 //---------------------------------------------------------------------- 00079 // return the extended area of a jet 00080 PseudoJet ClustSeqActAreaEG::area_4vector (const PseudoJet & jet) const { 00081 return _area_4vectors[jet.cluster_hist_index()]; 00082 } 00083 00084 //---------------------------------------------------------------------- 00085 bool ClustSeqActAreaEG::is_pure_ghost(const PseudoJet & jet) const 00086 { 00087 return _is_pure_ghost[jet.cluster_hist_index()]; 00088 } 00089 00090 //---------------------------------------------------------------------- 00091 bool ClustSeqActAreaEG::is_pure_ghost(int hist_ix) const 00092 { 00093 return hist_ix >= 0 ? _is_pure_ghost[hist_ix] : false; 00094 } 00095 00096 //---------------------------------------------------------------------- 00097 double ClustSeqActAreaEG::empty_area(const Selector & selector) const { 00098 // make sure that the selector applies jet by jet 00099 if (! selector.applies_jet_by_jet()){ 00100 throw Error("ClusterSequenceActiveAreaExplicitGhosts: empty area can only be computed from selectors applying jet by jet"); 00101 } 00102 00103 vector<PseudoJet> unclust = unclustered_particles(); 00104 double area = 0.0; 00105 for (unsigned iu = 0; iu < unclust.size(); iu++) { 00106 if (is_pure_ghost(unclust[iu]) && selector.pass(unclust[iu])) { 00107 area += _ghost_area; 00108 } 00109 } 00110 return area; 00111 } 00112 00113 //====================================================================== 00114 // sort out the areas 00115 void ClustSeqActAreaEG::_post_process() { 00116 00117 // first check for danger signals. 00118 // Establish largest ghost transverse momentum 00119 _max_ghost_perp2 = 0.0; 00120 for (int i = 0; i < _initial_n; i++) { 00121 if (_is_pure_ghost[i] && _jets[i].perp2() > _max_ghost_perp2) 00122 _max_ghost_perp2 = _jets[i].perp2(); 00123 } 00124 00125 // now find out if any of the particles are close to danger 00126 double danger_ratio = numeric_limits<double>::epsilon(); 00127 danger_ratio = danger_ratio * danger_ratio; 00128 _has_dangerous_particles = false; 00129 for (int i = 0; i < _initial_n; i++) { 00130 if (!_is_pure_ghost[i] && 00131 danger_ratio * _jets[i].perp2() <= _max_ghost_perp2) { 00132 _has_dangerous_particles = true; 00133 break; 00134 } 00135 } 00136 00137 if (_has_dangerous_particles) _warnings.warn("ClusterSequenceActiveAreaExplicitGhosts: \n ghosts not sufficiently soft wrt some of the input particles\n a common cause is (unphysical?) input particles with pt=0 but finite rapidity"); 00138 00139 // sort out sizes 00140 _areas.resize(_history.size()); 00141 _area_4vectors.resize(_history.size()); 00142 _is_pure_ghost.resize(_history.size()); 00143 00144 // copy(_jets.begin(), _jets.begin()+_initial_n, _area_4vectors.begin()); 00145 // for (int i = 0; i < _initial_n; i++) { 00146 // if (_is_pure_ghost[i]) { 00147 // _areas[i] = _ghost_area; 00148 // // normalise pt to be _ghost_area (NB we make use of fact that 00149 // // for initial particles, jet and clust_hist index are the same). 00150 // _area_4vectors[i] *= (_ghost_area/_jets[i].perp()); 00151 // } else { 00152 // _areas[i] = 0; 00153 // _area_4vectors[i].reset(0,0,0,0); 00154 // } 00155 // } 00156 00157 // First set up areas for the initial particles (ghost=_ghost_area, 00158 // real particles = 0); recall that _initial_n here is the number of 00159 // particles including ghosts 00160 for (int i = 0; i < _initial_n; i++) { 00161 if (_is_pure_ghost[i]) { 00162 _areas[i] = _ghost_area; 00163 // normalise pt to be _ghost_area (NB we make use of fact that 00164 // for initial particles, jet and clust_hist index are the same). 00165 //_area_4vectors[i] = (_ghost_area/_jets[i].perp()) * _jets[i]; 00166 _area_4vectors[i] = _jets[i]; 00167 _area_4vectors[i] *= (_ghost_area/_jets[i].perp()); 00168 } else { 00169 _areas[i] = 0; 00170 _area_4vectors[i] = PseudoJet(0.0,0.0,0.0,0.0); 00171 } 00172 } 00173 00174 // next follow the branching through and set up the areas 00175 // and ghost-nature at each step of the clustering (rather than 00176 // each jet). 00177 for (unsigned i = _initial_n; i < _history.size(); i++) { 00178 if (_history[i].parent2 == BeamJet) { 00179 _is_pure_ghost[i] = _is_pure_ghost[_history[i].parent1]; 00180 _areas[i] = _areas[_history[i].parent1]; 00181 _area_4vectors[i] = _area_4vectors[_history[i].parent1]; 00182 } else { 00183 _is_pure_ghost[i] = _is_pure_ghost[_history[i].parent1] && 00184 _is_pure_ghost[_history[i].parent2] ; 00185 _areas[i] = _areas[_history[i].parent1] + 00186 _areas[_history[i].parent2] ; 00187 _jet_def.recombiner()->recombine(_area_4vectors[_history[i].parent1], 00188 _area_4vectors[_history[i].parent2], 00189 _area_4vectors[i]); 00190 // _area_4vectors[i] = _area_4vectors[_history[i].parent1] + 00191 // _area_4vectors[_history[i].parent2] ; 00192 } 00193 00194 } 00195 00196 } 00197 00198 FASTJET_END_NAMESPACE 00199