1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
//----------------------------------------------------------------------
/// \file
/// \page Example07 07 - subtracting jet background contamination
///
/// fastjet subtraction example program.
///
/// run it with : ./07-subtraction < data/Pythia-Zp2jets-lhc-pileup-1ev.dat
///
/// Source code: 07-subtraction.cc
//----------------------------------------------------------------------
//STARTHEADER
// $Id: 07-subtraction.cc 2684 2011-11-14 07:41:44Z soyez $
//
// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
//
//----------------------------------------------------------------------
// This file is part of FastJet.
//
// FastJet is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// The algorithms that underlie FastJet have required considerable
// development and are described in hep-ph/0512210. If you use
// FastJet as part of work towards a scientific publication, please
// include a citation to the FastJet paper.
//
// FastJet is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FastJet. If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------
//ENDHEADER
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequenceArea.hh"
#include "fastjet/Selector.hh"
#include "fastjet/tools/JetMedianBackgroundEstimator.hh"
#include "fastjet/tools/Subtractor.hh"
#include <iostream> // needed for io
using namespace std;
using namespace fastjet;
int main(){
// read in input particles
//
// since we use here simulated data we can split the hard event
// from the full (i.e. with pileup added) one
//----------------------------------------------------------
vector<PseudoJet> hard_event, full_event;
// read in input particles. Keep the hard event generated by PYTHIA
// separated from the full event, so as to be able to gauge the
// "goodness" of the subtraction from the full event, which also
// includes pileup
double particle_maxrap = 5.0;
string line;
int nsub = 0; // counter to keep track of which sub-event we're reading
while (getline(cin, line)) {
istringstream linestream(line);
// take substrings to avoid problems when there are extra "pollution"
// characters (e.g. line-feed).
if (line.substr(0,4) == "#END") {break;}
if (line.substr(0,9) == "#SUBSTART") {
// if more sub events follow, make copy of first one (the hard one) here
if (nsub == 1) hard_event = full_event;
nsub += 1;
}
if (line.substr(0,1) == "#") {continue;}
double px,py,pz,E;
linestream >> px >> py >> pz >> E;
// you can construct
PseudoJet particle(px,py,pz,E);
// push event onto back of full_event vector
if (abs(particle.rap()) <= particle_maxrap) full_event.push_back(particle);
}
// if we have read in only one event, copy it across here...
if (nsub == 1) hard_event = full_event;
// if there was nothing in the event
if (nsub == 0) {
cerr << "Error: read empty event\n";
exit(-1);
}
// create a jet definition for the clustering
// We use the anti-kt algorithm with a radius of 0.5
//----------------------------------------------------------
double R = 0.5;
JetDefinition jet_def(antikt_algorithm, R);
// create an area definition for the clustering
//----------------------------------------------------------
// ghosts should go up to the acceptance of the detector or
// (with infinite acceptance) at least 2R beyond the region
// where you plan to investigate jets.
double ghost_maxrap = 6.0;
GhostedAreaSpec area_spec(ghost_maxrap);
AreaDefinition area_def(active_area, area_spec);
// run the jet clustering with the above jet and area definitions
// for both the hard and full event
//
// We retrieve the jets above 7 GeV in both case (note that the
// 7-GeV cut we be applied again later on after we subtract the jets
// from the full event)
// ----------------------------------------------------------
ClusterSequenceArea clust_seq_hard(hard_event, jet_def, area_def);
ClusterSequenceArea clust_seq_full(full_event, jet_def, area_def);
double ptmin = 7.0;
vector<PseudoJet> hard_jets = sorted_by_pt(clust_seq_hard.inclusive_jets(ptmin));
vector<PseudoJet> full_jets = sorted_by_pt(clust_seq_full.inclusive_jets(ptmin));
// Now turn to the estimation of the background (for the full event)
//
// There are different ways to do that. In general, this also
// requires clustering the particles that will be handled internally
// in FastJet.
//
// The suggested way to proceed is to use a BackgroundEstimator
// constructed from the following 3 arguments:
// - a jet definition used to cluster the particles.
// . We strongly recommend using the kt or Cambridge/Aachen
// algorithm (a warning will be issued otherwise)
// . The choice of the radius is a bit more subtle. R=0.4 has
// been chosen to limit the impact of hard jets; in samples of
// dominantly sparse events it may cause the UE/pileup to be
// underestimated a little, a slightly larger value (0.5 or
// 0.6) may be better.
// - An area definition for which we recommend the use of explicit
// ghosts (i.e. active_area_explicit_ghosts)
// As mentionned in the area example (06-area.cc), ghosts should
// extend sufficiently far in rapidity to cover the jets used in
// the computation of the background (see also the comment below)
// - A Selector specifying the range over which we will keep the
// jets entering the estimation of the background (you should
// thus make sure the ghosts extend far enough in rapidity to
// cover the range, a warning will be issued otherwise).
// In this particular example, the two hardest jets in the event
// are removed from the background estimation
// ----------------------------------------------------------
JetDefinition jet_def_bkgd(kt_algorithm, 0.4);
AreaDefinition area_def_bkgd(active_area_explicit_ghosts,
GhostedAreaSpec(ghost_maxrap));
Selector selector = SelectorAbsRapMax(4.5) * (!SelectorNHardest(2));
JetMedianBackgroundEstimator bkgd_estimator(selector, jet_def_bkgd, area_def_bkgd);
// To help manipulate the background estimator, we also provide a
// transformer that allows to apply directly the background
// subtraction on the jets. This will use the background estimator
// to compute rho for the jets to be subtracted.
// ----------------------------------------------------------
Subtractor subtractor(&bkgd_estimator);
// Finally, once we have an event, we can just tell the background
// estimator to use that list of particles
// This could be done directly when declaring the background
// estimator but the usage below can more easily be accomodated to a
// loop over a set of events.
// ----------------------------------------------------------
bkgd_estimator.set_particles(full_event);
// show a summary of what was done so far
// - the description of the algorithms, areas and ranges used
// - the background properties
// - the jets in the hard event
//----------------------------------------------------------
cout << "Main clustering:" << endl;
cout << " Ran: " << jet_def.description() << endl;
cout << " Area: " << area_def.description() << endl;
cout << " Particles up to |y|=" << particle_maxrap << endl;
cout << endl;
cout << "Background estimation:" << endl;
cout << " " << bkgd_estimator.description() << endl << endl;;
cout << " Giving, for the full event" << endl;
cout << " rho = " << bkgd_estimator.rho() << endl;
cout << " sigma = " << bkgd_estimator.sigma() << endl;
cout << endl;
cout << "Jets above " << ptmin << " GeV in the hard event (" << hard_event.size() << " particles)" << endl;
cout << "---------------------------------------\n";
printf("%5s %15s %15s %15s %15s\n","jet #", "rapidity", "phi", "pt", "area");
for (unsigned int i = 0; i < hard_jets.size(); i++) {
printf("%5u %15.8f %15.8f %15.8f %15.8f\n", i,
hard_jets[i].rap(), hard_jets[i].phi(), hard_jets[i].perp(),
hard_jets[i].area());
}
cout << endl;
// Once the background properties have been computed, subtraction
// can be applied on the jets. Subtraction is performed on the
// full 4-vector
//
// We output the jets before and after subtraction
// ----------------------------------------------------------
cout << "Jets above " << ptmin << " GeV in the full event (" << full_event.size() << " particles)" << endl;
cout << "---------------------------------------\n";
printf("%5s %15s %15s %15s %15s %15s %15s %15s\n","jet #", "rapidity", "phi", "pt", "area", "rap_sub", "phi_sub", "pt_sub");
unsigned int idx=0;
// get the subtracted jets
vector<PseudoJet> subtracted_jets = subtractor(full_jets);
for (unsigned int i=0; i<full_jets.size(); i++){
// re-apply the pt cut
if (subtracted_jets[i].perp2() >= ptmin*ptmin){
printf("%5u %15.8f %15.8f %15.8f %15.8f %15.8f %15.8f %15.8f\n", idx,
full_jets[i].rap(), full_jets[i].phi(), full_jets[i].perp(),
full_jets[i].area(),
subtracted_jets[i].rap(), subtracted_jets[i].phi(),
subtracted_jets[i].perp());
idx++;
}
}
return 0;
}
|