#ifndef __FASTJET_CONTRIB_TOOLS_RECLUSTER_HH__
#define __FASTJET_CONTRIB_TOOLS_RECLUSTER_HH__
// $Id: Recluster.hh 723 2014-07-30 09:11:01Z gsoyez $
//
// Copyright (c) 2014-, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
//
//----------------------------------------------------------------------
// This file is part of FastJet contrib.
//
// It 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.
//
// It 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 this code. If not, see .
//----------------------------------------------------------------------
#include
#include // to derive the ReclusterStructure from CompositeJetStructure
#include // to derive Recluster from Transformer
#include
#include
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
namespace contrib{
//----------------------------------------------------------------------
/// \class Recluster
/// Class that helps reclustering a jet with a new jet definition
///
/// The result of the reclustering is returned as a single PseudoJet
/// with a CompositeJet structure. The pieces of that PseudoJet will
/// be the individual subjets
///
/// When constructed from a JetDefinition, that definition will be
/// used to obtain the subjets. When constructed from a JetAlgorithm
/// and parameters (0 parameters for e+e-, just R or R and an extra
/// parameter for others) the recombination scheme will be taken as
/// the same one used to initially cluster the original jet.
///
/// The result of this transformer depends on its usage. There are two
/// typical use-cases: either we recluster one fat jet into subjets,
/// OR, we recluster the jet with a different jet alg. When Recluster
/// is created from a full jet definition. The last parameter of the
/// constructors below dicatate that behaviour: if "single" is true
/// (the default), a single jet, issued from a regular clustering is
/// returned (if there are more than one, the hardest is taken);
/// otherwise (single==false), the result will be a composite jet with
/// each subjet as pieces
///
/// Open points for discussion:
///
/// - do we add an option to force area support? [could be useful
/// e.g. for the filter with a subtractor where area support is
/// mandatory]
///
class Recluster : public Transformer {
public:
/// define a recluster that decomposes a jet into subjets using a
/// generic JetDefinition
///
/// \param subjet_def the jet definition applied to obtain the subjets
/// \param single when true, cluster the jet in a single jet (the
/// hardest one) with an associated ClusterSequence,
/// otherwise return a composite jet with subjets
/// as pieces.
Recluster(const JetDefinition & subjet_def, bool single=true)
: _subjet_def(subjet_def), _use_full_def(true), _single(single) {}
/// define a recluster that decomposes a jet into subjets using a
/// JetAlgorithm and its parameters
///
/// \param subjet_alg the jet algorithm applied to obtain the subjets
/// \param subjet_radius the jet radius if required
/// \param subjet_extra optional extra parameters for the jet algorithm (only when needed)
/// \param single when true, cluster the jet in a single jet (the
/// hardest one) with an associated ClusterSequence,
/// otherwise return a composite jet with subjets
/// as pieces.
///
/// Typically, for e+e- algoriothm you should use the third version
/// below with no parameters, for "standard" pp algorithms, just the
/// clustering radius has to be specified and for genkt-type of
/// algorithms, both the radius and the extra parameter have to be
/// specified.
Recluster(JetAlgorithm subjet_alg, double subjet_radius, double subjet_extra,
bool single=true)
: _subjet_alg(subjet_alg), _use_full_def(false),
_subjet_radius(subjet_radius), _has_subjet_radius(true),
_subjet_extra(subjet_extra), _has_subjet_extra(true), _single(single) {}
Recluster(JetAlgorithm subjet_alg, double subjet_radius, bool single=true)
: _subjet_alg(subjet_alg), _use_full_def(false),
_subjet_radius(subjet_radius), _has_subjet_radius(true),
_has_subjet_extra(false), _single(single) {}
Recluster(JetAlgorithm subjet_alg, bool single=true)
: _subjet_alg(subjet_alg), _use_full_def(false),
_has_subjet_radius(false), _has_subjet_extra(false), _single(single) {}
/// default dtor
virtual ~Recluster(){};
//----------------------------------------------------------------------
// standard Transformer behaviour inherited from the base class
// (i.e. result(), description() and structural info)
/// runs the reclustering and sets kept and rejected to be the jets of interest
/// (with non-zero rho, they will have been subtracted).
///
/// \param jet the jet that gets reclustered
/// \return the reclustered jet
virtual PseudoJet result(const PseudoJet & jet) const;
/// class description
virtual std::string description() const;
// the type of the associated structure
typedef CompositeJetStructure StructureType;
private:
/// set the reclustered elements in the simple case of C/A+C/A
void _recluster_cafilt(const std::vector & all_pieces,
std::vector & subjets,
double Rfilt) const;
/// set the reclustered elements in the generic re-clustering case
void _recluster_generic(const PseudoJet & jet,
std::vector & subjets,
const JetDefinition & subjet_def,
bool do_areas) const;
// a series of checks
//--------------------------------------------------------------------
/// get the pieces down to the fundamental pieces
bool _get_all_pieces(const PseudoJet &jet, std::vector &all_pieces) const;
/// get the common recombiner to all pieces (NULL if none)
const JetDefinition::Recombiner* _get_common_recombiner(const std::vector &all_pieces) const;
/// construct the proper jet definition ensuring that the recombiner
/// is taken from the underlying pieces (an error is thrown if the
/// pieces do no share a common recombiner)
void _build_jet_def_with_recombiner(const std::vector &all_pieces,
JetDefinition &subjet_def) const;
/// check if one can apply the simplified trick for C/A subjets
bool _check_ca(const std::vector &all_pieces,
const JetDefinition &subjet_def) const;
/// check if the jet (or all its pieces) have explicit ghosts
/// (assuming the jet has area support
///
/// Note that if the jet has an associated cluster sequence that is no
/// longer valid, an error will be thrown
bool _check_explicit_ghosts(const std::vector &all_pieces) const;
JetDefinition _subjet_def; ///< the jet definition to use to extract the subjets
JetAlgorithm _subjet_alg; ///< the jet algorithm to be used
bool _use_full_def; ///< true when the full JetDefinition is supplied to the ctor
double _subjet_radius; ///< the jet radius (only if needed for the jet alg)
bool _has_subjet_radius; ///< the subjet radius has been specified
double _subjet_extra; ///< the jet alg extra param (only if needed)
bool _has_subjet_extra; ///< the extra param has been specified
bool _single; ///< (true) return a single jet with a
///< regular clustering or (false) a
///< composite jet with subjets as pieces
static LimitedWarning _explicit_ghost_warning;
};
} // namespace contrib
FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh
#endif // __FASTJET_CONTRIB_TOOLS_RECLUSTER_HH__