// $Id: BottomUpSoftDrop.hh 1085 2017-10-11 02:16:59Z jthaler $
//
// Copyright (c) 2017-, Gavin P. Salam, Gregory Soyez, Jesse Thaler,
// Kevin Zhou, Frederic Dreyer
//
//----------------------------------------------------------------------
// 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 .
//----------------------------------------------------------------------
#ifndef __BOTTOMUPSOFTDROP_HH__
#define __BOTTOMUPSOFTDROP_HH__
#include "fastjet/ClusterSequence.hh"
#include "fastjet/WrappedStructure.hh"
#include "fastjet/tools/Transformer.hh"
#include
#include
// TODO
//
// - missing class description
//
// - check what to do when pta=ptb=0
// for the moment, we recombine both for multiple reasons
// . this avois breakingteh symemtry between pa and pb
// . it would be groomed in later steps anyway
// Note that this is slightly inconsistent with our use of
// > (instead of >=) in the cdt
FASTJET_BEGIN_NAMESPACE
namespace contrib{
// fwd declarations
class BottomUpSoftDrop;
class BottomUpSoftDropStructure;
class BottomUpSoftDropRecombiner;
class BottomUpSoftDropPlugin;
//----------------------------------------------------------------------
/// \class BottomUpSoftDrop
/// Implementation of the BottomUpSoftDrop transformer
///
/// Bottom-Up Soft drop grooms a jet by applying a modified
/// recombination scheme, where particles are recombined only if they
/// pass the Soft Drop condition
///
/// \f[
/// z < z_{\rm cut} (\theta/R0)^\beta
/// \f]
///
/// the groomed jet contains the particles remaining after this
/// pair-wise recombination
///
/// Note:
/// - one can use BottomUpSoftDrop on a full event with the
/// global_grooming(event) method.
/// - if two recombined particles a and b have momentum pta=ptb=0,
/// we recombine both.
///
class BottomUpSoftDrop : public Transformer {
public:
/// minimal constructor, which the jet algorithm to CA, sets the radius
/// to JetDefinition::max_allowable_R (practically equivalent to
/// infinity) and also tries to use a recombiner based on the one in
/// the jet definition of the particular jet being Soft Dropped.
///
/// \param beta the value for beta
/// \param symmetry_cut the value for symmetry_cut
/// \param R0 the value for R0
BottomUpSoftDrop(double beta, double symmetry_cut, double R0 = 1.0)
: _jet_def(cambridge_algorithm, JetDefinition::max_allowable_R),
_beta(beta),_symmetry_cut(symmetry_cut), _R0(R0),
_get_recombiner_from_jet(true) {}
/// alternative constructor which takes a specified jet algorithm
///
/// \param jet_alg the jet algorithm for the internal clustering (uses R=infty)
/// \param symmetry_cut the value of symmetry_cut
/// \param beta the value for beta
/// \param R0 the value for R0
BottomUpSoftDrop(const JetAlgorithm jet_alg, double beta, double symmetry_cut,
double R0 = 1.0)
: _jet_def(jet_alg, JetDefinition::max_allowable_R),
_beta(beta), _symmetry_cut(symmetry_cut), _R0(R0),
_get_recombiner_from_jet(true) {}
/// alternative ctor in which the full reclustering jet definition can
/// be specified.
///
/// \param jet_def the jet definition for the internal clustering
/// \param symmetry_cut the value of symmetry_cut
/// \param beta the value for beta
/// \param R0 the value for R0
BottomUpSoftDrop(const JetDefinition &jet_def, double beta, double symmetry_cut,
double R0 = 1.0)
: _jet_def(jet_def), _beta(beta), _symmetry_cut(symmetry_cut), _R0(R0),
_get_recombiner_from_jet(false) {}
/// action on a single jet
virtual PseudoJet result(const PseudoJet &jet) const;
/// global grooming on a full event
/// note: does not support jet areas
virtual std::vector global_grooming(const std::vector & event) const;
/// description
virtual std::string description() const;
// the type of the associated structure
typedef BottomUpSoftDropStructure StructureType;
private:
/// check if the jet has explicit_ghosts (knowing that there is an
/// area support)
bool _check_explicit_ghosts(const PseudoJet &jet) const;
/// see if there is a common recombiner among the pieces; if there
/// is return true and set jet_def_for_recombiner so that the
/// recombiner can be taken from that JetDefinition. Otherwise,
/// return false. 'assigned' is initially false; when true, each
/// time we meet a new jet definition, we'll check it shares the
/// same recombiner as jet_def_for_recombiner.
bool _check_common_recombiner(const PseudoJet &jet,
JetDefinition &jet_def_for_recombiner,
bool assigned=false) const;
JetDefinition _jet_def; ///< the internal jet definition
double _beta; ///< the value of beta
double _symmetry_cut; ///< the value of symmetry_cut
double _R0; ///< the value of R0
bool _get_recombiner_from_jet; ///< true for minimal constructor,
///< causes recombiner to be set equal
///< to that already used in the jet
///< (if it can be deduced)
};
//----------------------------------------------------------------------
/// The structure associated with a PseudoJet thas has gone through a
/// bottom/up SoftDrop transformer
class BottomUpSoftDropStructure : public WrappedStructure{
public:
/// default ctor
/// \param result_jet the jet for which we have to keep the structure
BottomUpSoftDropStructure(const PseudoJet & result_jet)
: WrappedStructure(result_jet.structure_shared_ptr()){}
/// description
virtual std::string description() const{
return "Bottom/Up Soft Dropped PseudoJet";
}
/// return the constituents that have been rejected
std::vector rejected() const{
return validated_cs()->childless_pseudojets();
}
/// return the other jets that may have been found along with the
/// result of the bottom/up Soft Drop
/// The resulting vector is sorted in pt
std::vector extra_jets() const {
return sorted_by_pt((!SelectorNHardest(1))(validated_cs()->inclusive_jets()));
}
/// return the value of beta that was used for this specific Soft Drop.
double beta() const {return _beta;}
/// return the value of symmetry_cut that was used for this specific Soft Drop.
double symmetry_cut() const {return _symmetry_cut;}
/// return the value of R0 that was used for this specific Soft Drop.
double R0() const {return _R0;}
protected:
friend class BottomUpSoftDrop; ///< to allow setting the internal information
private:
double _beta, _symmetry_cut, _R0;
};
//----------------------------------------------------------------------
/// Class for Soft Drop recombination
/// recombines the objects that are not vetoed by Bottom-Up SoftDrop
///
/// This recombiner only recombines, using the provided 'recombiner',
/// objects (i and j) that pass the following SoftDrop criterion:
///
/// min(pti, ptj) > zcut (pti+ptj) (theta_ij/R0)^beta
///
/// If the criterion fail, the hardest of i and j is kept and the
/// softest is rejected.
///
/// Note that this in not meant for standalone use [in particular
/// because it could lead to memory issues due to the rejected indices
/// stored internally].
///
/// This class is a direct adaptation of PruningRecombiner in Fastjet tools
class BottomUpSoftDropRecombiner : public JetDefinition::Recombiner {
public:
/// ctor
/// \param symmetry_cut value of cut on symmetry measure
/// \param beta avalue of beta parameter
/// \param recomb pointer to a recombiner to use to cluster pairs
BottomUpSoftDropRecombiner(double beta, double symmetry_cut, double R0,
const JetDefinition::Recombiner *recombiner)
: _beta(beta), _symmetry_cut(symmetry_cut), _R0sqr(R0*R0),
_recombiner(recombiner) {}
/// perform a recombination taking into account the Soft Drop
/// conditions
virtual void recombine(const PseudoJet &pa,
const PseudoJet &pb,
PseudoJet &pab) const;
/// returns the description of the recombiner
virtual std::string description() const {
std::ostringstream oss;
oss << "SoftDrop recombiner with symmetry_cut = " << _symmetry_cut
<< ", beta = " << _beta
<< ", and underlying recombiner = " << _recombiner->description();
return oss.str();
}
/// return the history indices that have been soft dropped away
const std::vector & rejected() const{ return _rejected;}
/// clears the list of rejected indices
///
/// If one decides to use this recombiner standalone, one has to
/// call this after each clustering in order for the rejected() vector
/// to remain sensible and not grow to infinite size.
void clear_rejected(){ _rejected.clear();}
private:
double _beta; ///< beta parameter
double _symmetry_cut; ///< value of symmetry_cut
double _R0sqr; ///< normalisation of the angular distance
const JetDefinition::Recombiner *_recombiner; ///< the underlying recombiner to use
mutable std::vector _rejected; ///< list of rejected history indices
};
//----------------------------------------------------------------------
/// \class BottomUpSoftDropPlugin
/// Class for a bottom/up Soft Drop algorithm, based on the Pruner plugin
///
/// This is an internal plugin that clusters the particles using the
/// BottomUpRecombiner.
///
/// See BottomUpRecombiner for a description of what bottom-up
/// SoftDrop does.
///
/// Note that this is an internal class used by the BottomUpSoftDrop
/// transformer and it is not meant to be used as a standalone
/// clustering tool.
class BottomUpSoftDropPlugin : public JetDefinition::Plugin {
public:
/// ctor
/// \param jet_def the jet definition to be used for the
/// internal clustering
/// \param symmetry_cut value of cut on symmetry measure
/// \param beta value of beta parameter
BottomUpSoftDropPlugin(const JetDefinition &jet_def, double beta, double symmetry_cut,
double R0 = 1.0)
: _jet_def(jet_def), _beta(beta), _symmetry_cut(symmetry_cut), _R0(R0) {}
/// the actual clustering work for the plugin
virtual void run_clustering(ClusterSequence &input_cs) const;
/// description of the plugin
virtual std::string description() const;
/// returns the radius
virtual double R() const {return _jet_def.R();}
private:
JetDefinition _jet_def; ///< the internal jet definition
double _beta; ///< beta parameter
double _symmetry_cut; ///< value of symmetry_cut
double _R0; ///< normalisation of the angular distance
};
}
FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh
#endif // __BOTTOMUPSOFTDROP_HH__