31#include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh"
36FASTJET_BEGIN_NAMESPACE
39typedef ClusterSequenceActiveAreaExplicitGhosts ClustSeqActAreaEG;
42LimitedWarning ClustSeqActAreaEG::_warnings;
46void ClustSeqActAreaEG::_add_ghosts (
47 const GhostedAreaSpec & ghost_spec) {
50 ghost_spec.add_ghosts(_jets);
53 for (
unsigned i = _initial_hard_n; i < _jets.size(); i++) {
55 _is_pure_ghost.push_back(
true);
59 _ghost_area = ghost_spec.actual_ghost_area();
60 _n_ghosts = ghost_spec.n_ghosts();
74 return _n_ghosts * _ghost_area;
93 return hist_ix >= 0 ? _is_pure_ghost[hist_ix] :
false;
100 throw Error(
"ClusterSequenceActiveAreaExplicitGhosts: empty area can only be computed from selectors applying jet by jet");
104 double area_local = 0.0;
105 for (
unsigned iu = 0; iu < unclust.size(); iu++) {
107 area_local += _ghost_area;
115void ClustSeqActAreaEG::_post_process() {
119 _max_ghost_perp2 = 0.0;
120 for (
int i = 0; i < _initial_n; i++) {
121 if (_is_pure_ghost[i] && _jets[i].perp2() > _max_ghost_perp2)
122 _max_ghost_perp2 = _jets[i].perp2();
126 double danger_ratio = numeric_limits<double>::epsilon();
127 danger_ratio = danger_ratio * danger_ratio;
128 _has_dangerous_particles =
false;
129 for (
int i = 0; i < _initial_n; i++) {
130 if (!_is_pure_ghost[i] &&
131 danger_ratio * _jets[i].perp2() <= _max_ghost_perp2) {
132 _has_dangerous_particles =
true;
137 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");
140 _areas.resize(_history.size());
141 _area_4vectors.resize(_history.size());
142 _is_pure_ghost.resize(_history.size());
160 for (
int i = 0; i < _initial_n; i++) {
161 if (_is_pure_ghost[i]) {
162 _areas[i] = _ghost_area;
171 _area_4vectors[i].reset_momentum(_jets[i]);
172 _area_4vectors[i] *= (_ghost_area/_jets[i].perp());
175 _area_4vectors[i] = PseudoJet(0.0,0.0,0.0,0.0);
182 for (
unsigned i = _initial_n; i < _history.size(); i++) {
183 if (_history[i].parent2 == BeamJet) {
184 _is_pure_ghost[i] = _is_pure_ghost[_history[i].parent1];
185 _areas[i] = _areas[_history[i].parent1];
186 _area_4vectors[i] = _area_4vectors[_history[i].parent1];
188 _is_pure_ghost[i] = _is_pure_ghost[_history[i].parent1] &&
189 _is_pure_ghost[_history[i].parent2] ;
190 _areas[i] = _areas[_history[i].parent1] +
191 _areas[_history[i].parent2] ;
192 _jet_def.recombiner()->recombine(_area_4vectors[_history[i].parent1],
193 _area_4vectors[_history[i].parent2],
virtual PseudoJet area_4vector(const PseudoJet &jet) const override
returns a four vector corresponding to the sum (E-scheme) of the ghost four-vectors composing the jet...
virtual double area(const PseudoJet &jet) const override
returns the area of a jet
virtual bool is_pure_ghost(const PseudoJet &jet) const override
true if a jet is made exclusively of ghosts
double total_area() const
returns the total area under study
virtual double empty_area(const Selector &selector) const override
return the total area, corresponding to a given Selector, that consists of unclustered ghosts
std::vector< PseudoJet > unclustered_particles() const
return the set of particles that have not been clustered.
base class corresponding to errors that can be thrown by FastJet
Class to contain pseudojets, including minimal information of use to jet-clustering routines.
int cluster_hist_index() const
return the cluster_hist_index, intended to be used by clustering routines.
Class that encodes information about cuts and other selection criteria that can be applied to PseudoJ...
bool pass(const PseudoJet &jet) const
return true if the jet passes the selection
bool applies_jet_by_jet() const
returns true if this can be applied jet by jet