//STARTHEADER
// $Id: JetDefinition.hh 2687 2011-11-14 11:17:51Z 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 .
//----------------------------------------------------------------------
//ENDHEADER
#ifndef __FASTJET_JETDEFINITION_HH__
#define __FASTJET_JETDEFINITION_HH__
#include
#include "fastjet/internal/numconsts.hh"
#include "fastjet/PseudoJet.hh"
#include
#include
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
/// return a string containing information about the release
// NB: (implemented in ClusterSequence.cc but defined here because
// this is a visible location)
std::string fastjet_version_string();
//======================================================================
/// the various options for the algorithmic strategy to adopt in
/// clustering events with kt and cambridge style algorithms.
enum Strategy {
/// fastest form about 500..10^4
N2MinHeapTiled = -4,
/// fastest from about 50..500
N2Tiled = -3,
/// legacy
N2PoorTiled = -2,
/// fastest below 50
N2Plain = -1,
/// worse even than the usual N^3 algorithms
N3Dumb = 0,
/// automatic selection of the best (based on N)
Best = 1,
/// best of the NlnN variants -- best overall for N>10^4.
/// (Does not work for R>=2pi)
NlnN = 2,
/// legacy N ln N using 3pi coverage of cylinder.
/// (Does not work for R>=2pi)
NlnN3pi = 3,
/// legacy N ln N using 4pi coverage of cylinder
NlnN4pi = 4,
/// Chan's closest pair method (in a variant with 4pi coverage),
/// for use exclusively with the Cambridge algorithm.
/// (Does not work for R>=2pi)
NlnNCam4pi = 14,
/// Chan's closest pair method (in a variant with 2pi+2R coverage),
/// for use exclusively with the Cambridge algorithm.
/// (Does not work for R>=2pi)
NlnNCam2pi2R = 13,
/// Chan's closest pair method (in a variant with 2pi+minimal extra
/// variant), for use exclusively with the Cambridge algorithm.
/// (Does not work for R>=2pi)
NlnNCam = 12, // 2piMultD
/// the plugin has been used...
plugin_strategy = 999
};
//======================================================================
/// \enum JetAlgorithm
/// the various families of jet-clustering algorithm
enum JetAlgorithm {
/// the longitudinally invariant kt algorithm
kt_algorithm=0,
/// the longitudinally invariant variant of the cambridge algorithm
/// (aka Aachen algoithm).
cambridge_algorithm=1,
/// like the k_t but with distance measures
/// dij = min(1/kti^2,1/ktj^2) Delta R_{ij}^2 / R^2
/// diB = 1/kti^2
antikt_algorithm=2,
/// like the k_t but with distance measures
/// dij = min(kti^{2p},ktj^{2p}) Delta R_{ij}^2 / R^2
/// diB = 1/kti^{2p}
/// where p = extra_param()
genkt_algorithm=3,
/// a version of cambridge with a special distance measure for particles
/// whose pt is < extra_param()
cambridge_for_passive_algorithm=11,
/// a version of genkt with a special distance measure for particles
/// whose pt is < extra_param() [relevant for passive areas when p<=0]
genkt_for_passive_algorithm=13,
//.................................................................
/// the e+e- kt algorithm
ee_kt_algorithm=50,
/// the e+e- genkt algorithm (R > 2 and p=1 gives ee_kt)
ee_genkt_algorithm=53,
//.................................................................
/// any plugin algorithm supplied by the user
plugin_algorithm = 99,
//.................................................................
/// the value for the jet algorithm in a JetDefinition for which
/// no algorithm has yet been defined
undefined_jet_algorithm = 999
};
/// make standard Les Houches nomenclature JetAlgorithm (algorithm is general
/// recipe without the parameters) backward-compatible with old JetFinder
typedef JetAlgorithm JetFinder;
/// provide other possible names for the Cambridge/Aachen algorithm
const JetAlgorithm aachen_algorithm = cambridge_algorithm;
const JetAlgorithm cambridge_aachen_algorithm = cambridge_algorithm;
//======================================================================
/// the various recombination schemes
enum RecombinationScheme {
/// summing the 4-momenta
E_scheme=0,
/// pt weighted recombination of y,phi (and summing of pt's)
/// with preprocessing to make things massless by rescaling E=|\vec p|
pt_scheme=1,
/// pt^2 weighted recombination of y,phi (and summing of pt's)
/// with preprocessing to make things massless by rescaling E=|\vec p|
pt2_scheme=2,
/// pt weighted recombination of y,phi (and summing of pt's)
/// with preprocessing to make things massless by rescaling |\vec p|->=E
Et_scheme=3,
/// pt^2 weighted recombination of y,phi (and summing of pt's)
/// with preprocessing to make things massless by rescaling |\vec p|->=E
Et2_scheme=4,
/// pt weighted recombination of y,phi (and summing of pt's), with
/// no preprocessing
BIpt_scheme=5,
/// pt^2 weighted recombination of y,phi (and summing of pt's)
/// no preprocessing
BIpt2_scheme=6,
/// for the user's external scheme
external_scheme = 99
};
// forward declaration, needed in order to specify interface for the
// plugin.
class ClusterSequence;
//======================================================================
/// @ingroup basic_classes
/// \class JetDefinition
/// class that is intended to hold a full definition of the jet
/// clusterer
class JetDefinition {
public:
/// forward declaration of a class that allows the user to introduce
/// their own plugin
class Plugin;
// forward declaration of a class that will provide the
// recombination scheme facilities and/or allow a user to
// extend these facilities
class Recombiner;
/// constructor with alternative ordering or arguments -- note that
/// we have not provided a default jet finder, to avoid ambiguous
/// JetDefinition() constructor.
JetDefinition(JetAlgorithm jet_algorithm_in,
double R_in,
RecombinationScheme recomb_scheme_in = E_scheme,
Strategy strategy_in = Best) {
*this = JetDefinition(jet_algorithm_in, R_in, strategy_in, recomb_scheme_in, 1);
}
/// constructor for algorithms that have no free parameters
/// (e.g. ee_kt_algorithm)
JetDefinition(JetAlgorithm jet_algorithm_in,
RecombinationScheme recomb_scheme_in = E_scheme,
Strategy strategy_in = Best) {
double dummyR = 0.0;
*this = JetDefinition(jet_algorithm_in, dummyR, strategy_in, recomb_scheme_in, 0);
}
/// constructor for algorithms that require R + one extra parameter to be set
/// (the gen-kt series for example)
JetDefinition(JetAlgorithm jet_algorithm_in,
double R_in,
double xtra_param_in,
RecombinationScheme recomb_scheme_in = E_scheme,
Strategy strategy_in = Best) {
*this = JetDefinition(jet_algorithm_in, R_in, strategy_in, recomb_scheme_in, 2);
set_extra_param(xtra_param_in);
}
/// constructor in a form that allows the user to provide a pointer
/// to an external recombiner class (which must remain valid for the
/// life of the JetDefinition object).
JetDefinition(JetAlgorithm jet_algorithm_in,
double R_in,
const Recombiner * recombiner_in,
Strategy strategy_in = Best) {
*this = JetDefinition(jet_algorithm_in, R_in, external_scheme, strategy_in);
_recombiner = recombiner_in;
}
/// constructor for case with 0 parameters (ee_kt_algorithm) and
/// and external recombiner
JetDefinition(JetAlgorithm jet_algorithm_in,
const Recombiner * recombiner_in,
Strategy strategy_in = Best) {
*this = JetDefinition(jet_algorithm_in, external_scheme, strategy_in);
_recombiner = recombiner_in;
}
/// constructor allowing the extra parameter to be set and a pointer to
/// a recombiner
JetDefinition(JetAlgorithm jet_algorithm_in,
double R_in,
double xtra_param_in,
const Recombiner * recombiner_in,
Strategy strategy_in = Best) {
*this = JetDefinition(jet_algorithm_in, R_in, external_scheme, strategy_in);
_recombiner = recombiner_in;
set_extra_param(xtra_param_in);
}
/// a default constructor which creates a jet definition that is in
/// a well-defined internal state, but not actually usable for jet
/// clustering.
JetDefinition() {
*this = JetDefinition(undefined_jet_algorithm, 1.0);
}
// /// a default constructor
// JetDefinition() {
// *this = JetDefinition(kt_algorithm, 1.0);
// }
/// constructor based on a pointer to a user's plugin; the object
/// pointed to must remain valid for the whole duration of existence
/// of the JetDefinition and any related ClusterSequences
JetDefinition(const Plugin * plugin_in) {
_plugin = plugin_in;
_strategy = plugin_strategy;
_Rparam = _plugin->R();
_jet_algorithm = plugin_algorithm;
set_recombination_scheme(E_scheme);
}
/// constructor to fully specify a jet-definition (together with
/// information about how algorithically to run it).
///
/// the ordering of arguments here is old and deprecated (except
/// as the common constructor for internal use)
JetDefinition(JetAlgorithm jet_algorithm_in,
double R_in,
Strategy strategy_in,
RecombinationScheme recomb_scheme_in = E_scheme,
int nparameters_in = 1);
/// R values larger than max_allowable_R are not allowed.
///
/// We use a value of 1000, substantially smaller than
/// numeric_limits::max(), to leave room for the convention
/// within PseudoJet of setting unphysical (infinite) rapidities to
/// +-(MaxRap + abs(pz())), where MaxRap is 10^5.
static const double max_allowable_R; //= 1000.0;
/// set the recombination scheme to the one provided
void set_recombination_scheme(RecombinationScheme);
/// set the recombiner class to the one provided
void set_recombiner(const Recombiner * recomb) {
if (_recombiner_shared()) _recombiner_shared.reset(recomb);
_recombiner = recomb;
_default_recombiner = DefaultRecombiner(external_scheme);
}
/// calling this tells the JetDefinition to handle the deletion of
/// the recombiner when it is no longer used
void delete_recombiner_when_unused();
/// return a pointer to the plugin
const Plugin * plugin() const {return _plugin;};
/// allows to let the JetDefinition handle the deletion of the
/// plugin when it is no longer used
void delete_plugin_when_unused();
/// return information about the definition...
JetAlgorithm jet_algorithm () const {return _jet_algorithm ;}
/// same as above for backward compatibility
JetAlgorithm jet_finder () const {return _jet_algorithm ;}
double R () const {return _Rparam ;}
// a general purpose extra parameter, whose meaning depends on
// the algorithm, and may often be unused.
double extra_param () const {return _extra_param ;}
Strategy strategy () const {return _strategy ;}
RecombinationScheme recombination_scheme() const {
return _default_recombiner.scheme();}
/// (re)set the jet finder
void set_jet_algorithm(JetAlgorithm njf) {_jet_algorithm = njf;}
/// same as above for backward compatibility
void set_jet_finder(JetAlgorithm njf) {_jet_algorithm = njf;}
/// (re)set the general purpose extra parameter
void set_extra_param(double xtra_param) {_extra_param = xtra_param;}
/// return a pointer to the currently defined recombiner.
///
/// Warning: the pointer may be to an internal recombiner (for
/// default recombination schemes), in which case if the
/// JetDefinition becomes invalid (e.g. is deleted), the pointer
/// will then point to an object that no longer exists.
///
/// Note also that if you copy a JetDefinition with a default
/// recombination scheme, then the two copies will have distinct
/// recombiners, and return different recombiner() pointers.
const Recombiner * recombiner() const {
return _recombiner == 0 ? & _default_recombiner : _recombiner;}
/// returns true if the current jet definitions shares the same
/// recombiner as teh one passed as an argument
bool has_same_recombiner(const JetDefinition &other_jd) const;
/// return a textual description of the current jet definition
std::string description() const;
public:
//======================================================================
/// @ingroup advanced_usage
/// \class Recombiner
/// An abstract base class that will provide the recombination scheme
/// facilities and/or allow a user to extend these facilities
class Recombiner {
public:
/// return a textual description of the recombination scheme
/// implemented here
virtual std::string description() const = 0;
/// recombine pa and pb and put result into pab
virtual void recombine(const PseudoJet & pa, const PseudoJet & pb,
PseudoJet & pab) const = 0;
/// routine called to preprocess each input jet (to make all input
/// jets compatible with the scheme requirements (e.g. massless).
virtual void preprocess(PseudoJet & ) const {};
/// a destructor to be replaced if necessary in derived classes...
virtual ~Recombiner() {};
/// pa += pb in the given recombination scheme. Not virtual -- the
/// user should have no reason to want to redefine this!
inline void plus_equal(PseudoJet & pa, const PseudoJet & pb) const {
// put result in a temporary location in case the recombiner
// does something funny (ours doesn't, but who knows about the
// user's)
PseudoJet pres;
recombine(pa,pb,pres);
pa = pres;
}
};
//======================================================================
/// @ingroup advanced_usage
/// \class DefaultRecombiner
/// A class that will provide the recombination scheme facilities and/or
/// allow a user to extend these facilities
///
/// This class is derived from the (abstract) class Recombiner. It
/// simply "sums" PseudoJets using a specified recombination scheme
/// (E-scheme by default)
class DefaultRecombiner : public Recombiner {
public:
DefaultRecombiner(RecombinationScheme recomb_scheme = E_scheme) :
_recomb_scheme(recomb_scheme) {}
virtual std::string description() const;
/// recombine pa and pb and put result into pab
virtual void recombine(const PseudoJet & pa, const PseudoJet & pb,
PseudoJet & pab) const;
virtual void preprocess(PseudoJet & p) const;
/// return the index of the recombination scheme
RecombinationScheme scheme() const {return _recomb_scheme;}
private:
RecombinationScheme _recomb_scheme;
};
//======================================================================
/// @ingroup advanced_usage
/// \class Plugin
/// a class that allows a user to introduce their own "plugin" jet
/// finder
///
/// Note that all the plugins provided with FastJet are derived from
/// this class
class Plugin{
public:
/// return a textual description of the jet-definition implemented
/// in this plugin
virtual std::string description() const = 0;
/// given a ClusterSequence that has been filled up with initial
/// particles, the following function should fill up the rest of the
/// ClusterSequence, using the following member functions of
/// ClusterSequence:
/// - plugin_do_ij_recombination(...)
/// - plugin_do_iB_recombination(...)
virtual void run_clustering(ClusterSequence &) const = 0;
virtual double R() const = 0;
/// return true if there is specific support for the measurement
/// of passive areas, in the sense that areas determined from all
/// particles below the ghost separation scale will be a passive
/// area. [If you don't understand this, ignore it!]
virtual bool supports_ghosted_passive_areas() const {return false;}
/// set the ghost separation scale for passive area determinations
/// in future runs (strictly speaking that makes the routine
/// a non const, so related internal info must be stored as a mutable)
virtual void set_ghost_separation_scale(double scale) const;
virtual double ghost_separation_scale() const {return 0.0;}
/// if this returns false then a warning will be given
/// whenever the user requests "exclusive" jets from the
/// cluster sequence
virtual bool exclusive_sequence_meaningful() const {return false;}
/// a destructor to be replaced if necessary in derived classes...
virtual ~Plugin() {};
};
private:
JetAlgorithm _jet_algorithm;
double _Rparam;
double _extra_param ; ///< parameter whose meaning varies according to context
Strategy _strategy ;
const Plugin * _plugin;
SharedPtr _plugin_shared;
// when we use our own recombiner it's useful to point to it here
// so that we don't have to worry about deleting it etc...
DefaultRecombiner _default_recombiner;
const Recombiner * _recombiner;
SharedPtr _recombiner_shared;
};
//-------------------------------------------------------------------------------
// helper functions to build a jet made of pieces
//
// These functions include an options recombiner used to compute the
// total composite jet momentum
// -------------------------------------------------------------------------------
/// build a "CompositeJet" from the vector of its pieces
///
/// In this case, E-scheme recombination is assumed to compute the
/// total momentum
PseudoJet join(const std::vector & pieces, const JetDefinition::Recombiner & recombiner);
/// build a MergedJet from a single PseudoJet
PseudoJet join(const PseudoJet & j1,
const JetDefinition::Recombiner & recombiner);
/// build a MergedJet from 2 PseudoJet
PseudoJet join(const PseudoJet & j1, const PseudoJet & j2,
const JetDefinition::Recombiner & recombiner);
/// build a MergedJet from 3 PseudoJet
PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3,
const JetDefinition::Recombiner & recombiner);
/// build a MergedJet from 4 PseudoJet
PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3, const PseudoJet & j4,
const JetDefinition::Recombiner & recombiner);
FASTJET_END_NAMESPACE
#endif // __FASTJET_JETDEFINITION_HH__