Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

ClusterSequenceAreaBase.cc

Go to the documentation of this file.
00001 
00002 //STARTHEADER
00003 // $Id: ClusterSequenceAreaBase.cc 1110 2008-02-28 11:58:55Z cacciari $
00004 //
00005 // Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam
00006 //
00007 //----------------------------------------------------------------------
00008 // This file is part of FastJet.
00009 //
00010 //  FastJet is free software; you can redistribute it and/or modify
00011 //  it under the terms of the GNU General Public License as published by
00012 //  the Free Software Foundation; either version 2 of the License, or
00013 //  (at your option) any later version.
00014 //
00015 //  The algorithms that underlie FastJet have required considerable
00016 //  development and are described in hep-ph/0512210. If you use
00017 //  FastJet as part of work towards a scientific publication, please
00018 //  include a citation to the FastJet paper.
00019 //
00020 //  FastJet is distributed in the hope that it will be useful,
00021 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 //  GNU General Public License for more details.
00024 //
00025 //  You should have received a copy of the GNU General Public License
00026 //  along with FastJet; if not, write to the Free Software
00027 //  Foundation, Inc.:
00028 //      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00029 //----------------------------------------------------------------------
00030 //ENDHEADER
00031 
00032 
00033 
00034 
00035 #include "fastjet/ClusterSequenceAreaBase.hh"
00036 #include <algorithm>
00037 
00038 FASTJET_BEGIN_NAMESPACE
00039 
00040 using namespace std;
00041 
00042 
00044 LimitedWarning ClusterSequenceAreaBase::_warnings;
00045 
00046 //----------------------------------------------------------------------
00051 double ClusterSequenceAreaBase::empty_area(const RangeDefinition & range) const {
00052   double empty = range.area();
00053   vector<PseudoJet> incl_jets(inclusive_jets(0.0));
00054   for (unsigned i = 0; i < incl_jets.size(); i++) {
00055     if (range.is_in_range(incl_jets[i])) empty -= area(incl_jets[i]);
00056   }
00057   return empty;
00058 }
00059 
00060 double ClusterSequenceAreaBase::median_pt_per_unit_area(const RangeDefinition & range) const {
00061   return median_pt_per_unit_something(range,false);
00062 }
00063 
00064 double ClusterSequenceAreaBase::median_pt_per_unit_area_4vector(const RangeDefinition & range) const {
00065   return median_pt_per_unit_something(range,true);
00066 }
00067 
00068 
00069 //----------------------------------------------------------------------
00073 double ClusterSequenceAreaBase::median_pt_per_unit_something(
00074                 const RangeDefinition & range, bool use_area_4vector) const {
00075 
00076   double median, sigma, mean_area;
00077   get_median_rho_and_sigma(range, use_area_4vector, median, sigma, mean_area);
00078   return median;
00079 
00080 }
00081 
00082 
00083 //----------------------------------------------------------------------
00087 void ClusterSequenceAreaBase::parabolic_pt_per_unit_area(
00088        double & a, double & b, const RangeDefinition & range, 
00089        double exclude_above, bool use_area_4vector) const {
00090   
00091   int n=0;
00092   int n_excluded = 0;
00093   double mean_f=0, mean_x2=0, mean_x4=0, mean_fx2=0; 
00094 
00095   vector<PseudoJet> incl_jets = inclusive_jets();
00096 
00097   for (unsigned i = 0; i < incl_jets.size(); i++) {
00098     if (range.is_in_range(incl_jets[i])) {
00099       double this_area;
00100       if ( use_area_4vector ) {
00101           this_area = area_4vector(incl_jets[i]).perp();     
00102       } else {
00103           this_area = area(incl_jets[i]);
00104       }
00105       double f = incl_jets[i].perp()/this_area;
00106       if (exclude_above <= 0.0 || f < exclude_above) {
00107         double x = incl_jets[i].rap(); double x2 = x*x;
00108         mean_f   += f;
00109         mean_x2  += x2;
00110         mean_x4  += x2*x2;
00111         mean_fx2 += f*x2;
00112         n++;
00113       } else {
00114         n_excluded++;
00115       }
00116     }
00117   }
00118 
00119   if (n <= 1) {
00120     // meaningful results require at least two jets inside the
00121     // area -- mind you if there are empty jets we should be in 
00122     // any case doing something special...
00123     a = 0.0;
00124     b = 0.0;
00125   } else {
00126     mean_f   /= n;
00127     mean_x2  /= n;
00128     mean_x4  /= n;
00129     mean_fx2 /= n;
00130     
00131     b = (mean_f*mean_x2 - mean_fx2)/(mean_x2*mean_x2 - mean_x4);
00132     a = mean_f - b*mean_x2;
00133   }
00134   //cerr << "n_excluded = "<< n_excluded << endl;
00135 }
00136 
00137 
00138 
00139 
00140 void ClusterSequenceAreaBase::get_median_rho_and_sigma(
00141             const RangeDefinition & range, bool use_area_4vector,
00142             double & median, double & sigma, double & mean_area) const {
00143 
00144   _check_jet_alg_good_for_median();
00145 
00146   vector<double> pt_over_areas;
00147   vector<PseudoJet> incl_jets = inclusive_jets();
00148   double total_area  = 0.0;
00149   double total_njets = 0;
00150 
00151   for (unsigned i = 0; i < incl_jets.size(); i++) {
00152     if (range.is_in_range(incl_jets[i])) {
00153       double this_area;
00154       if (use_area_4vector) {
00155           this_area = area_4vector(incl_jets[i]).perp();
00156       } else {
00157           this_area = area(incl_jets[i]);
00158       }
00159       pt_over_areas.push_back(incl_jets[i].perp()/this_area);
00160       total_area  += this_area;
00161       total_njets += 1.0;
00162     }
00163   }
00164 
00165   // there is nothing inside our region, so answer will always be zero
00166   if (pt_over_areas.size() == 0) {
00167     median = 0.0;
00168     sigma  = 0.0;
00169     mean_area = 0.0;
00170     return;
00171   }
00172   
00173   // get median (pt/area) [this is the "old" median definition. It considers
00174   // only the "real" jets in calculating the median, i.e. excluding the
00175   // only-ghost ones]
00176   sort(pt_over_areas.begin(), pt_over_areas.end());
00177 
00178   // now get the median & error, accounting for empty jets
00179   // define the fractions of distribution at median, median-1sigma
00180   double posn[2] = {0.5, (1.0-0.6827)/2.0};
00181   double res[2];
00182   
00183   double n_empty = n_empty_jets(range);
00184   total_njets += n_empty;
00185   total_area  += empty_area(range);
00186 
00187   for (int i = 0; i < 2; i++) {
00188     double nj_median_pos = 
00189       (pt_over_areas.size()-1 + n_empty)*posn[i] - n_empty;
00190     double nj_median_ratio;
00191     if (nj_median_pos >= 0 && pt_over_areas.size() > 1) {
00192       int int_nj_median = int(nj_median_pos);
00193       nj_median_ratio = 
00194         pt_over_areas[int_nj_median] * (int_nj_median+1-nj_median_pos)
00195         + pt_over_areas[int_nj_median+1] * (nj_median_pos - int_nj_median);
00196     } else {
00197       nj_median_ratio = 0.0;
00198     }
00199     res[i] = nj_median_ratio;
00200   }
00201   median = res[0];
00202   double error  = res[0] - res[1];
00203   mean_area = total_area / total_njets;
00204   sigma  = error * sqrt(mean_area);
00205 }
00206 
00207 
00212 vector<PseudoJet> ClusterSequenceAreaBase::subtracted_jets(const double rho,
00213                                                            const double ptmin) 
00214                                                            const {
00215   vector<PseudoJet> sub_jets;
00216   vector<PseudoJet> jets = sorted_by_pt(inclusive_jets(ptmin));
00217   for (unsigned i=0; i<jets.size(); i++) {
00218      PseudoJet sub_jet = subtracted_jet(jets[i],rho);
00219      sub_jets.push_back(sub_jet);
00220   }
00221   return sub_jets;
00222 }
00223 
00228 vector<PseudoJet> ClusterSequenceAreaBase::subtracted_jets(
00229                                                  const RangeDefinition & range, 
00230                                                  const double ptmin)
00231                                                  const {
00232   double rho = median_pt_per_unit_area_4vector(range);
00233   return subtracted_jets(rho,ptmin);
00234 }
00235 
00236 
00238 PseudoJet ClusterSequenceAreaBase::subtracted_jet(const PseudoJet & jet,
00239                                                   const double rho) const {
00240   PseudoJet area4vect = area_4vector(jet);
00241   PseudoJet sub_jet;
00242   // sanity check
00243   if (rho*area4vect.perp() < jet.perp() ) { 
00244     sub_jet = jet - rho*area4vect;
00245   } else { sub_jet = PseudoJet(0.0,0.0,0.0,0.0); }
00246   
00247   // make sure the subtracted jet has the same index 
00248   // (i.e. "looks like") the original jet
00249   sub_jet.set_cluster_hist_index(jet.cluster_hist_index());
00250   
00251   return sub_jet;
00252 }
00253 
00254 
00258 PseudoJet ClusterSequenceAreaBase::subtracted_jet(const PseudoJet & jet,
00259                                        const RangeDefinition & range) const {
00260   double rho = median_pt_per_unit_area_4vector(range);
00261   PseudoJet sub_jet = subtracted_jet(jet, rho);
00262   return sub_jet;
00263 }
00264 
00265 
00267 double ClusterSequenceAreaBase::subtracted_pt(const PseudoJet & jet,
00268                                               const double rho,
00269                                               bool use_area_4vector) const {
00270   if ( use_area_4vector ) { 
00271      PseudoJet sub_jet = subtracted_jet(jet,rho);
00272      return sub_jet.perp();
00273   } else {
00274      return jet.perp() - rho*area(jet);
00275   }
00276 }  
00277 
00278 
00282 double ClusterSequenceAreaBase::subtracted_pt(const PseudoJet & jet,
00283                                               const RangeDefinition & range,
00284                                               bool use_area_4vector) const {
00285   if ( use_area_4vector ) { 
00286      PseudoJet sub_jet = subtracted_jet(jet,range);
00287      return sub_jet.perp();
00288   } else {
00289      double rho = median_pt_per_unit_area(range);
00290      return subtracted_pt(jet,rho,false);
00291   }
00292 }  
00293 
00294 
00296 void ClusterSequenceAreaBase::_check_jet_alg_good_for_median() const {
00297   if (jet_def().jet_algorithm() != kt_algorithm
00298       && jet_def().jet_algorithm() != cambridge_algorithm
00299       && jet_def().jet_algorithm() !=  cambridge_for_passive_algorithm) {
00300     _warnings.warn("ClusterSequenceAreaBase: jet_def being used may not be suitable for estimating diffuse backgrounds (good options are kt, cam)");
00301   }
00302 }
00303 
00304 
00305 
00306 FASTJET_END_NAMESPACE

Generated on Fri Aug 15 13:45:28 2008 for fastjet by  doxygen 1.4.2