// Nsubjettiness Package
// Questions/Comments? jthaler@jthaler.net
//
// Copyright (c) 2011-14
// Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
//
// $Id: MeasureFunction.hh 678 2014-06-12 20:43:03Z jthaler $
//----------------------------------------------------------------------
// 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 __FASTJET_CONTRIB_MEASUREFUNCTION_HH__
#define __FASTJET_CONTRIB_MEASUREFUNCTION_HH__
#include "fastjet/PseudoJet.hh"
#include
#include
#include
#include
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
namespace contrib{
///////
//
// TauComponents
// (eventually we might want to put this in a separate header file)
//
///////
/// \class TauComponents
// This class creates a wrapper for the various tau/subtau values calculated in Njettiness. This class allows Njettiness access to these variables
// without ever having to do the calculation itself. It takes in subtau numerators and tau denominator from MeasureFunction
// and outputs tau numerator, and normalized tau and subtau.
class TauComponents {
public:
// empty constructor necessary to initialize tau_components in Njettiness
// later set correctly in Njettiness::getTau function
TauComponents() {
_jet_pieces_numerator.resize(1, 0.0);
_beam_piece_numerator = 0.0;
_denominator = 0;
_numerator = 0;
_jet_pieces.resize(1, 0.0);
_beam_piece = 0.0;
_tau = 0;
_has_denominator = false;
_has_beam = false;
}
// This constructor takes input vector and double and calculates all necessary tau components
TauComponents(std::vector jet_pieces_numerator, double beam_piece_numerator, double denominator, bool has_denominator, bool has_beam)
: _jet_pieces_numerator(jet_pieces_numerator),
_beam_piece_numerator(beam_piece_numerator),
_denominator(denominator),
_has_denominator(has_denominator),
_has_beam(has_beam) {
if (!_has_denominator) assert(_denominator == 1.0); //make sure no effect from _denominator if _has_denominator is false
if (!_has_beam) assert (_beam_piece_numerator == 0.0); //make sure no effect from _beam_piece_numerator if _has_beam is false
_numerator = _beam_piece_numerator;
_jet_pieces.resize(_jet_pieces_numerator.size(),0.0);
for (unsigned j = 0; j < _jet_pieces_numerator.size(); j++) {
_jet_pieces[j] = _jet_pieces_numerator[j]/_denominator;
_numerator += _jet_pieces_numerator[j];
}
_beam_piece = _beam_piece_numerator/_denominator;
_tau = _numerator/_denominator;
}
// return values
std::vector jet_pieces_numerator() const { return _jet_pieces_numerator; }
double beam_piece_numerator() const { return _beam_piece_numerator; }
double denominator() const { return _denominator; }
double numerator() const { return _numerator; }
bool has_denominator() const { return _has_denominator; }
bool has_beam() const { return _has_beam; }
std::vector jet_pieces() const { return _jet_pieces; }
double beam_piece() const { return _beam_piece; }
double tau() const { return _tau; }
private:
// these values are input in the constructor
std::vector _jet_pieces_numerator;
double _beam_piece_numerator;
double _denominator;
bool _has_denominator; //added so that TauComponents knows if denominator is used or not
bool _has_beam; //added so that TauComponents knows if beam regions is used or not
// these values are derived from above values
std::vector _jet_pieces;
double _beam_piece;
double _numerator;
double _tau;
};
///////
//
// Measure Function
//
///////
//------------------------------------------------------------------------
/// \class MeasureFunction
// This class calculates the tau_N of a jet given a specific measure.
// It serves as a base class for calculating tau_N according to different measures that are implemented
// in further derived classes, but does not define a particular measure itself.
class MeasureFunction {
public:
//These functions define the measure by which tau_N is calculated,
//and are overloaded by the various measures below
// Distanes to axes. These are called many times, so need to be as fast as possible
virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const = 0;
virtual double beam_distance_squared(const fastjet::PseudoJet& particle) const = 0;
// The actual measures used in N-(sub)jettiness
virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const = 0;
virtual double beam_numerator(const fastjet::PseudoJet& particle) const = 0;
// a possible normalization factor
virtual double denominator(const fastjet::PseudoJet& particle) const = 0;
//------
// The functions below call the above functions and are not virtual
//------
// Return all of the necessary TauComponents for specific input particles and axes
// Also have optional pointers to get out information about partitioning
TauComponents result(const std::vector& particles, const std::vector& axes) const;
// Just getting tau value if that is all that is needed
double tau(const std::vector& particles, const std::vector& axes) const {
return result(particles,axes).tau();
}
// Create the partitioning and stores internally
std::vector get_partition(const std::vector& particles, const std::vector& axes, PseudoJet * beamPartitionStorage = NULL) const;
// Essentially same as get_partition, but in the form needed for the jet algorithm
std::vector > get_partition_list(const std::vector& particles, const std::vector& axes) const;
// calculates the tau result using an existing partition
TauComponents result_from_partition(const std::vector& jet_partitioning, const std::vector& axes, PseudoJet * beamPartitionStorage = NULL) const;
// shorthand for squaring
static inline double sq(double x) {return x*x;}
//virtual destructor
virtual ~MeasureFunction(){}
protected:
//bool set by derived classes to choose whether or not to use the denominator
bool _has_denominator;
bool _has_beam;
// This constructor allows _has_denominator to be set by derived classes
MeasureFunction(bool has_denominator = true, bool has_beam = true) : _has_denominator(has_denominator), _has_beam(has_beam) {}
};
/// \class DefaultNormalizedMeasureFunction
// This class is the default measure, inheriting from the class above. This class will calculate tau_N
// of a jet according to this measure. This measure is defined as the pT of the particle multiplied by deltaR
// to the power of beta. This class includes the normalization factor determined by R0
class DefaultNormalizedMeasureFunction : public MeasureFunction {
public:
DefaultNormalizedMeasureFunction(double beta, double R0, double Rcutoff, bool normalized = true)
: MeasureFunction(normalized), _beta(beta), _R0(R0), _Rcutoff(Rcutoff) {}
virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
return particle.squared_distance(axis);
}
virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const {
return sq(_Rcutoff);
}
virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const{
return particle.perp() * std::pow(jet_distance_squared(particle,axis),_beta/2.0);
}
virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
return particle.perp() * std::pow(_Rcutoff,_beta);
}
virtual double denominator(const fastjet::PseudoJet& particle) const {
return particle.perp() * std::pow(_R0,_beta);
}
private:
double _beta;
double _R0;
double _Rcutoff;
};
//------------------------------------------------------------------------
/// \class DefaultUnnormalizedMeasureFunction
// This class is the unnormalized default measure, inheriting from the class above. The only difference from above
// is that the denominator is defined to be 1.0 by setting _has_denominator to false.
class DefaultUnnormalizedMeasureFunction : public DefaultNormalizedMeasureFunction {
public:
// Since all methods are identical, UnnormalizedMeasure inherits directly
// from NormalizedMeasure. R0 is a dummy value since the value of R0 is unecessary for this class,
// and the "false" flag sets _has_denominator in MeasureFunction to false so no denominator is used.
DefaultUnnormalizedMeasureFunction(double beta, double Rcutoff)
: DefaultNormalizedMeasureFunction(beta, std::numeric_limits::quiet_NaN(), Rcutoff, false) {}
};
//------------------------------------------------------------------------
/// \class GeometricMeasureFunction
// This class is the geometic measure, inheriting from the class above. This class will calculate tau_N
// of a jet according to this measure. This measure is defined by the Lorentz dot product between
// the particle and the axis. This class includes normalization of tau_N.
class GeometricMeasureFunction : public MeasureFunction {
public:
// Right now, we are hard coded for beam_beta = 1.0, but that will need to change
GeometricMeasureFunction(double jet_beta, double Rcutoff) :
MeasureFunction(false), // doesn't have denominator
_jet_beta(jet_beta), _beam_beta(1.0), _Rcutoff(Rcutoff) {}
virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
fastjet::PseudoJet lightAxis = lightFrom(axis);
double pseudoRsquared = 2.0*dot_product(lightFrom(axis),particle)/(lightAxis.pt()*particle.pt());
return pseudoRsquared;
}
virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const {
return sq(_Rcutoff);
}
virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
fastjet::PseudoJet lightAxis = lightFrom(axis);
double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(lightAxis.pt(),_beam_beta - 1.0);
return particle.pt() * weight * std::pow(jet_distance_squared(particle,axis),_jet_beta/2.0);
}
virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(particle.pt()/particle.e(),_beam_beta - 1.0);
return particle.pt() * weight * std::pow(_Rcutoff,_jet_beta);
}
virtual double denominator(const fastjet::PseudoJet& /*particle*/) const {
return std::numeric_limits::quiet_NaN();
}
private:
double _jet_beta;
double _beam_beta;
double _Rcutoff;
// create light-like axis
fastjet::PseudoJet lightFrom(const fastjet::PseudoJet& input) const {
double length = sqrt(pow(input.px(),2) + pow(input.py(),2) + pow(input.pz(),2));
return fastjet::PseudoJet(input.px()/length,input.py()/length,input.pz()/length,1.0);
}
};
} //namespace contrib
FASTJET_END_NAMESPACE
#endif // __FASTJET_CONTRIB_MEASUREFUNCTION_HH__