00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00054 double ClusterSequenceAreaBase::empty_area(const RangeDefinition & range) const {
00055
00056 if (has_explicit_ghosts()) {return 0.0;}
00057 else { return empty_area_from_jets(inclusive_jets(0.0), range);}
00058
00059 }
00060
00061
00066 double ClusterSequenceAreaBase::empty_area_from_jets(
00067 const std::vector<PseudoJet> & all_jets,
00068 const RangeDefinition & range) const {
00069
00070 double empty = range.area();
00071 for (unsigned i = 0; i < all_jets.size(); i++) {
00072 if (range.is_in_range(all_jets[i])) empty -= area(all_jets[i]);
00073 }
00074 return empty;
00075 }
00076
00077 double ClusterSequenceAreaBase::median_pt_per_unit_area(const RangeDefinition & range) const {
00078 return median_pt_per_unit_something(range,false);
00079 }
00080
00081 double ClusterSequenceAreaBase::median_pt_per_unit_area_4vector(const RangeDefinition & range) const {
00082 return median_pt_per_unit_something(range,true);
00083 }
00084
00085
00086
00090 double ClusterSequenceAreaBase::median_pt_per_unit_something(
00091 const RangeDefinition & range, bool use_area_4vector) const {
00092
00093 double median, sigma, mean_area;
00094 get_median_rho_and_sigma(range, use_area_4vector, median, sigma, mean_area);
00095 return median;
00096
00097 }
00098
00099
00100
00104 void ClusterSequenceAreaBase::parabolic_pt_per_unit_area(
00105 double & a, double & b, const RangeDefinition & range,
00106 double exclude_above, bool use_area_4vector) const {
00107
00108 int n=0;
00109 int n_excluded = 0;
00110 double mean_f=0, mean_x2=0, mean_x4=0, mean_fx2=0;
00111
00112 vector<PseudoJet> incl_jets = inclusive_jets();
00113
00114 for (unsigned i = 0; i < incl_jets.size(); i++) {
00115 if (range.is_in_range(incl_jets[i])) {
00116 double this_area;
00117 if ( use_area_4vector ) {
00118 this_area = area_4vector(incl_jets[i]).perp();
00119 } else {
00120 this_area = area(incl_jets[i]);
00121 }
00122 double f = incl_jets[i].perp()/this_area;
00123 if (exclude_above <= 0.0 || f < exclude_above) {
00124 double x = incl_jets[i].rap(); double x2 = x*x;
00125 mean_f += f;
00126 mean_x2 += x2;
00127 mean_x4 += x2*x2;
00128 mean_fx2 += f*x2;
00129 n++;
00130 } else {
00131 n_excluded++;
00132 }
00133 }
00134 }
00135
00136 if (n <= 1) {
00137
00138
00139
00140 a = 0.0;
00141 b = 0.0;
00142 } else {
00143 mean_f /= n;
00144 mean_x2 /= n;
00145 mean_x4 /= n;
00146 mean_fx2 /= n;
00147
00148 b = (mean_f*mean_x2 - mean_fx2)/(mean_x2*mean_x2 - mean_x4);
00149 a = mean_f - b*mean_x2;
00150 }
00151
00152 }
00153
00154
00155
00156 void ClusterSequenceAreaBase::get_median_rho_and_sigma(
00157 const RangeDefinition & range, bool use_area_4vector,
00158 double & median, double & sigma, double & mean_area) const {
00159
00160 vector<PseudoJet> incl_jets = inclusive_jets();
00161 get_median_rho_and_sigma(incl_jets, range, use_area_4vector,
00162 median, sigma, mean_area, true);
00163 }
00164
00165
00166 void ClusterSequenceAreaBase::get_median_rho_and_sigma(
00167 const vector<PseudoJet> & all_jets,
00168 const RangeDefinition & range, bool use_area_4vector,
00169 double & median, double & sigma, double & mean_area,
00170 bool all_are_incl) const {
00171
00172 _check_jet_alg_good_for_median();
00173
00174 vector<double> pt_over_areas;
00175 double total_area = 0.0;
00176 double total_njets = 0;
00177
00178 for (unsigned i = 0; i < all_jets.size(); i++) {
00179 if (range.is_in_range(all_jets[i])) {
00180 double this_area;
00181 if (use_area_4vector) {
00182 this_area = area_4vector(all_jets[i]).perp();
00183 } else {
00184 this_area = area(all_jets[i]);
00185 }
00186 pt_over_areas.push_back(all_jets[i].perp()/this_area);
00187 total_area += this_area;
00188 total_njets += 1.0;
00189 }
00190 }
00191
00192
00193 if (pt_over_areas.size() == 0) {
00194 median = 0.0;
00195 sigma = 0.0;
00196 mean_area = 0.0;
00197 return;
00198 }
00199
00200
00201
00202
00203 sort(pt_over_areas.begin(), pt_over_areas.end());
00204
00205
00206
00207 double posn[2] = {0.5, (1.0-0.6827)/2.0};
00208 double res[2];
00209
00210 double n_empty, empty_a;
00211 if (has_explicit_ghosts()) {
00212
00213
00214
00215
00216
00217 empty_a = 0.0;
00218 n_empty = 0;
00219 } else if (all_are_incl) {
00220
00221 empty_a = empty_area(range);
00222 n_empty = n_empty_jets(range);
00223 } else {
00224
00225
00226
00227 empty_a = empty_area_from_jets(all_jets, range);
00228 mean_area = total_area / total_njets;
00229 n_empty = empty_a / mean_area;
00230 }
00231
00232
00233 total_njets += n_empty;
00234 total_area += empty_a;
00235
00236 for (int i = 0; i < 2; i++) {
00237 double nj_median_pos =
00238 (pt_over_areas.size()-1 + n_empty)*posn[i] - n_empty;
00239 double nj_median_ratio;
00240 if (nj_median_pos >= 0 && pt_over_areas.size() > 1) {
00241 int int_nj_median = int(nj_median_pos);
00242 nj_median_ratio =
00243 pt_over_areas[int_nj_median] * (int_nj_median+1-nj_median_pos)
00244 + pt_over_areas[int_nj_median+1] * (nj_median_pos - int_nj_median);
00245 } else {
00246 nj_median_ratio = 0.0;
00247 }
00248 res[i] = nj_median_ratio;
00249 }
00250 median = res[0];
00251 double error = res[0] - res[1];
00252 mean_area = total_area / total_njets;
00253 sigma = error * sqrt(mean_area);
00254 }
00255
00256
00261 vector<PseudoJet> ClusterSequenceAreaBase::subtracted_jets(const double rho,
00262 const double ptmin)
00263 const {
00264 vector<PseudoJet> sub_jets;
00265 vector<PseudoJet> jets = sorted_by_pt(inclusive_jets(ptmin));
00266 for (unsigned i=0; i<jets.size(); i++) {
00267 PseudoJet sub_jet = subtracted_jet(jets[i],rho);
00268 sub_jets.push_back(sub_jet);
00269 }
00270 return sub_jets;
00271 }
00272
00277 vector<PseudoJet> ClusterSequenceAreaBase::subtracted_jets(
00278 const RangeDefinition & range,
00279 const double ptmin)
00280 const {
00281 double rho = median_pt_per_unit_area_4vector(range);
00282 return subtracted_jets(rho,ptmin);
00283 }
00284
00285
00287 PseudoJet ClusterSequenceAreaBase::subtracted_jet(const PseudoJet & jet,
00288 const double rho) const {
00289 PseudoJet area4vect = area_4vector(jet);
00290 PseudoJet sub_jet;
00291
00292 if (rho*area4vect.perp() < jet.perp() ) {
00293 sub_jet = jet - rho*area4vect;
00294 } else { sub_jet = PseudoJet(0.0,0.0,0.0,0.0); }
00295
00296
00297
00298 sub_jet.set_cluster_hist_index(jet.cluster_hist_index());
00299 sub_jet.set_user_index(jet.user_index());
00300
00301 return sub_jet;
00302 }
00303
00304
00308 PseudoJet ClusterSequenceAreaBase::subtracted_jet(const PseudoJet & jet,
00309 const RangeDefinition & range) const {
00310 double rho = median_pt_per_unit_area_4vector(range);
00311 PseudoJet sub_jet = subtracted_jet(jet, rho);
00312 return sub_jet;
00313 }
00314
00315
00317 double ClusterSequenceAreaBase::subtracted_pt(const PseudoJet & jet,
00318 const double rho,
00319 bool use_area_4vector) const {
00320 if ( use_area_4vector ) {
00321 PseudoJet sub_jet = subtracted_jet(jet,rho);
00322 return sub_jet.perp();
00323 } else {
00324 return jet.perp() - rho*area(jet);
00325 }
00326 }
00327
00328
00332 double ClusterSequenceAreaBase::subtracted_pt(const PseudoJet & jet,
00333 const RangeDefinition & range,
00334 bool use_area_4vector) const {
00335 if ( use_area_4vector ) {
00336 PseudoJet sub_jet = subtracted_jet(jet,range);
00337 return sub_jet.perp();
00338 } else {
00339 double rho = median_pt_per_unit_area(range);
00340 return subtracted_pt(jet,rho,false);
00341 }
00342 }
00343
00344
00346 void ClusterSequenceAreaBase::_check_jet_alg_good_for_median() const {
00347 if (jet_def().jet_algorithm() != kt_algorithm
00348 && jet_def().jet_algorithm() != cambridge_algorithm
00349 && jet_def().jet_algorithm() != cambridge_for_passive_algorithm) {
00350 _warnings.warn("ClusterSequenceAreaBase: jet_def being used may not be suitable for estimating diffuse backgrounds (good options are kt, cam)");
00351 }
00352 }
00353
00354
00355
00356 FASTJET_END_NAMESPACE