Page MenuHomeHEPForge

No OneTemporary

Index: contrib/contribs/SDFPlugin/trunk/NEWS
===================================================================
--- contrib/contribs/SDFPlugin/trunk/NEWS (revision 1519)
+++ contrib/contribs/SDFPlugin/trunk/NEWS (revision 1520)
@@ -1,8 +1,10 @@
+2025/04/29: release version 1.0.2
+- added modulo_2 option for flavour recombination
+
2025/01/15: release of version 1.0.1
- header file more readable
-2025/01/14: release of version 1.0.0
+2025/01/14: release of version 1.0.0
- First fjcontrib release of SDFPlugin
- this is now the reference version for SDFPlugin
superseding https://github.com/jetflav/SDFlavPlugin
-
Index: contrib/contribs/SDFPlugin/trunk/README
===================================================================
--- contrib/contribs/SDFPlugin/trunk/README (revision 1519)
+++ contrib/contribs/SDFPlugin/trunk/README (revision 1520)
@@ -1,75 +1,91 @@
SDFPlugin
=========
This code provides an implementation of the SoftDrop Flavour (SDF)
-algorithm presented in
+algorithm presented in
> Practical Jet Flavour Through NNLO,
> by Simone Caletti, Andrew J. Larkoski, Simone Marzani and Daniel Reichelt
> https://arxiv.org/pdf/2205.01109
To learn how to use the library, the ['example-SDF.cc'](example-SDF.cc) code is
a good place to get started
**The SDFPlugin code needs FastJet ≥ 3.4.1 to compile**
**The SDFPlugin depends on the IFNPlugin and the RecursiveTools contrib, which are also distributed with fjcontrib**
Specifically
- It relies on the flavour structure implemented in FlavInfo.cc from IFNPlugin
- It uses the Soft Drop algorithm and the reclusterings implemented in RecursiveTools
Main principles of SDF
---------------------
The SDF algorithm uses a base jet (clustered with any IRC safe algorithm)
-and assign a flavour label to such a jet in an IRC safe way,
+and assign a flavour label to such a jet in an IRC safe way,
at least up to NNLO QCD.
The flavour label is built as the net flavour of the particles surviving
-the Soft Drop procedure.
-Differently from the standard Soft Drop procedure, in the SDF algorithm
+the Soft Drop procedure.
+Differently from the standard Soft Drop procedure, in the SDF algorithm
the jet is reclustered using the JADE algorithm, instead of C/A as customary.
The Soft Drop procedure applied by SDF is used just for the flavour assignement
and must be applied again (with the desired algorithm for the reclustering)
if the user wants to look at the properties of the groomed jet.
Code Structure
--------------
The main interface to the SDF algorithm is ['SDFPlugin.hh'](SDFPlugin.hh)
// we start with a base jet definition (should be either
// antikt_algorithm or cambridge_algorithm, or their e+e- variants)
JetDefinition base_jet_def(antikt_algorithm, 0.4);
// enable it to track flavours (default is net flavour)
FlavRecombiner flav_recombiner;
+ // to unable modulo_2 flavour replace the line above with
+ // FlavRecombiner flav_recombiner=FlavRecombiner::modulo_2;
base_jet_def.set_recombiner(&flav_recombiner);
+ // We define the SDFlavourCalc with
+ // default parameters
+ // beta = 2
+ // zcut = 0.1
+ // R = 0.4
+ // modulo_2 = false
SDFlavourCalc sdFlavCalc;
vector<PseudoJet> sdflav_jets = base_jet_def(event);
sdFlavCalc(sdflav_jets);
The SDFlavourCalc class can be found in include/fastjet/contrib/SDFPlugin.hh
and returns the Soft Drop Flavour applying JADE reclustering and Soft Drop
to the original jet.
Default parameters used by the Soft Drop and the reclustering procedures are
- beta = 2
- zcut = 0.1
- R = 0.4
+- modulo_2 = false
They can be changed when defining the SDFlavourCalc object, e.g.
- SDFlavourCalc sdFlavCalc(1,0.2,0.5);
+ SDFlavourCalc sdFlavCalc(1,0.2,0.5,true);
where the new parameters are
- beta = 1
- zcut = 0.2
- R = 0.5
+- modulo_2 = true
+
+The modulo_2 boolean variable unable the modulo_2 flavour recombination scheme.
+The default option is false, and corresponds to the net flavour recombination.
+When comparing SDFlavourCalc and the base jet be sure to use the same
+flavour recombination. This can be done
+
+ sdFlavCalc.check_flav_recombination(base_jet_def);
Pushing zcut very close to zero one can check that the SDFPlugin returns
-the same flavour as the standard net flavour of the initial jet.
+the same flavour than the initial jet.
Note: SDF is only defined for beta > 0
-
Index: contrib/contribs/SDFPlugin/trunk/SDFPlugin.cc
===================================================================
--- contrib/contribs/SDFPlugin/trunk/SDFPlugin.cc (revision 1519)
+++ contrib/contribs/SDFPlugin/trunk/SDFPlugin.cc (revision 1520)
@@ -1,60 +1,81 @@
// -*- C++ -*-
//
// Copyright (c) -,
//
//----------------------------------------------------------------------
// 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 <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------
#include "fastjet/contrib/SDFPlugin.hh"
#include "fastjet/contrib/FlavInfo.hh"
+//#include "include/fastjet/contrib/SDFPlugin.hh"
#include <istream>
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
namespace contrib{
//using fastjet::contrib::FlavInfo;
//using fastjet::contrib::FlavHistory;
void SDFlavourCalc::operator()(fastjet::PseudoJet& jet) {
fastjet::ClusterSequence cs(jet.constituents(), p_plugin.get());
cs.exclusive_jets_up_to(1);
std::vector<fastjet::PseudoJet> sdjets = p_sd->operator()(cs.exclusive_jets_up_to(1));
if(sdjets.size() != 1) jet.set_user_info(new fastjet::contrib::FlavHistory(fastjet::contrib::FlavInfo()));
std::vector<fastjet::PseudoJet> sdj = sdjets[0].constituents();
fastjet::contrib::FlavInfo flavj = fastjet::contrib::FlavHistory::current_flavour_of(sdj[0]);
for(size_t i=1; i < sdj.size(); i++){
flavj = flavj+fastjet::contrib::FlavHistory::current_flavour_of(sdj[i]);
}
+ // apply modulo_2 if required
+ if(_modulo_2) {
+ flavj.apply_modulo_2();
+ //std::cout<<"Applied modulo_2 flavour recombination\n";
+ }
// if(jet.constituents().size() != sdj.size()) {
// std::cout<<jet.constituents().size()<<" "<<sdj.size()<<"\n";
// for(auto p: jet.constituents()) std::cout<<FlavHistory::current_flavour_of(p).description()<<"\n";
// std::cout<<"---------\n";
// for(auto p: sdj) std::cout<<FlavHistory::current_flavour_of(p).description()<<"\n";
// std::cout<<"**********\n";
// }
jet.set_user_info(new fastjet::contrib::FlavHistory(flavj));
}
void SDFlavourCalc::operator()(std::vector<fastjet::PseudoJet>& jets) {
for(fastjet::PseudoJet& jet: jets) {
operator()(jet);
}
}
+void SDFlavourCalc::check_flav_recombination(const fastjet::JetDefinition &jet_def) const{
+ const auto *flav_recombiner = dynamic_cast<const fastjet::contrib::FlavRecombiner*>(jet_def.recombiner());
+ if (flav_recombiner) {
+ if (_modulo_2) {
+ if (flav_recombiner->flav_summation() != fastjet::contrib::FlavRecombiner::modulo_2) {
+ throw fastjet::Error("SDFlavourCalc: modulo_2 is activated, but JetDefinition uses flav_summation != modulo_2");
+ }
+ } else {
+ if (flav_recombiner->flav_summation() != fastjet::contrib::FlavRecombiner::net) {
+ throw fastjet::Error("SDFlavourCalc: modulo_2 is not activated, but JetDefinition uses flav_summation != net");
+ }
+ }
+ };
+ };
+
} // namespace contrib
FASTJET_END_NAMESPACE
Index: contrib/contribs/SDFPlugin/trunk/include/fastjet/contrib/SDFPlugin.hh
===================================================================
--- contrib/contribs/SDFPlugin/trunk/include/fastjet/contrib/SDFPlugin.hh (revision 1519)
+++ contrib/contribs/SDFPlugin/trunk/include/fastjet/contrib/SDFPlugin.hh (revision 1520)
@@ -1,71 +1,86 @@
#ifndef SDFLAV_DEF
#define SDFLAV_DEF
#include "fastjet/contrib/SoftDrop.hh"
#include "fastjet/JadePlugin.hh"
#include "fastjet/contrib/Recluster.hh"
#include <memory>
+
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
namespace contrib{
/**
* @class SDFlavourCalc
* @brief A utility class applying SoftDrop algorithm with JADE reclustering
* as required by the SDFPlugin algorithm.
*/
class SDFlavourCalc {
-public:
+ public:
/** Constructor for SDFlavourCalc
*
* Initializes the SoftDrop algorithm with specified parameters for beta, zcut and R.
- * The constructor also sets up a reclusterign scheme using the JADE plugin.
+ * The constructor also sets up a reclustering scheme using the JADE plugin.
*
* @param beta SoftDrop beta parameter, controlling the angular exponent. Must be strictly positive. Default is 2.
* @param zcut SoftDrop zcut parameter, defining the energy fraction threshold. Default is 0.1.
- * @param R The jet rdius parameter. Default is 0.4.
+ * @param R The jet radius parameter. Default is 0.4.
+ * @param modulo_2 If true uses modulo_2 flavour recombination, otherwise net is used. Default is false.
*/
SDFlavourCalc(const double beta = 2,
const double zcut = 0.1,
- const double R = 0.4) : p_sd(new fastjet::contrib::SoftDrop(beta, zcut,
+ const double R = 0.4,
+ const bool modulo_2 = false) : _modulo_2(modulo_2),
+ p_sd(new fastjet::contrib::SoftDrop(beta, zcut,
fastjet::contrib::RecursiveSymmetryCutBase::SymmetryMeasure::scalar_z,
R,
std::numeric_limits<double>::infinity(),
fastjet::contrib::RecursiveSymmetryCutBase::RecursionChoice::larger_pt,
0)),
p_plugin(new fastjet::JadePlugin()),
p_recluster(new fastjet::Recluster(fastjet::JetDefinition(p_plugin.get()))){
p_sd->set_reclustering(true,p_recluster.get());
}
+ // flag to activate modulo_2 flavour recombination
+ bool _modulo_2;
+
/// Unique pointer to the SoftDrop instance
std::unique_ptr<fastjet::contrib::SoftDrop> p_sd;
/// Unique pointer to the JADE plugin for reclustering
std::unique_ptr<fastjet::JetDefinition::Plugin> p_plugin;
/// Unique pointer to the Recluster instance
std::unique_ptr<fastjet::Recluster> p_recluster;
/**
* @brief Applies the SoftDrop procedure to a single jet.
*
* @param jets A reference to a PseudoJet to process.
*/
void operator()(fastjet::PseudoJet& jet);
/**
* @brief Applies the SoftDrop procedure to a vector of jets.
*
* @param jets A vector of PseudoJets to process.
*/
void operator()(std::vector<fastjet::PseudoJet>& jets);
+ /**
+ * @brief Check that flavour recombination is the same between base jet definition
+ * and the SDFlavourCalc class
+ *
+ * @param jet_def A JetDefinition used to cluster the base jet
+ */
+ void check_flav_recombination(const fastjet::JetDefinition &jet_def) const;
+
};
-} // namespace contrib
+} // namespace contrib
FASTJET_END_NAMESPACE
#endif
Index: contrib/contribs/SDFPlugin/trunk/example-SDF.cc
===================================================================
--- contrib/contribs/SDFPlugin/trunk/example-SDF.cc (revision 1519)
+++ contrib/contribs/SDFPlugin/trunk/example-SDF.cc (revision 1520)
@@ -1,101 +1,114 @@
#include <iostream>
#include <iomanip>
#include "fastjet/PseudoJet.hh"
-#include "fastjet/contrib/SDFPlugin.hh"
+#include "fastjet/contrib/SDFPlugin.hh"
#include "fastjet/contrib/FlavInfo.hh"
+//#include "include/fastjet/contrib/SDFPlugin.hh"
using namespace std;
using namespace fastjet;
using namespace fastjet::contrib;
// forward declaration to make things clearer
void read_event(vector<PseudoJet> &event);
//----------------------------------------------------------------------
int main(int iargc, char **argv){
// give user control over printout (mainly relevant for make check)
// usage: "./example-SDF [nevmax [njetmax]] < ../data/pythia8_Zq_vshort.dat"
unsigned int nevmax = 2;
unsigned int njetmax = 1;
if (iargc > 1) nevmax = stoi(argv[1]);
if (iargc > 2) njetmax = stoi(argv[2]);
// print banner for FastJet at the start, so it doesn't mix
// into the other output
- ClusterSequence::print_banner();
+ ClusterSequence::print_banner();
// we start with a base jet definition (should be either
// antikt_algorithm or cambridge_algorithm, or their e+e- variants)
JetDefinition base_jet_def(antikt_algorithm, 0.4);
// enable it to track flavours (default is net flavour)
FlavRecombiner flav_recombiner;
+ // to unable modulo_2 flavour replace the line above with
+ // FlavRecombiner flav_recombiner=FlavRecombiner::modulo_2;
base_jet_def.set_recombiner(&flav_recombiner);
+ // We define the SDFlavourCalc with
+ // default parameters
+ // beta = 2
+ // zcut = 0.1
+ // R = 0.4
+ // modulo_2 = false
SDFlavourCalc sdFlavCalc;
+ // check flavour recombination is chosen
+ // consistently between SDF and the base jet
+ sdFlavCalc.check_flav_recombination(base_jet_def);
+
// loop over some number of events
int n_events = 10;
for (int iev = 0; iev < n_events && iev < nevmax; iev++) {
cout << "\n#---------------------------------------------------------------\n";
cout << "# read event " << iev;
- // read in input particles: see that routine for info
+ // read in input particles: see that routine for info
// on how to set up the PseudoJets with flavour information
vector<PseudoJet> event;
read_event(event);
cout<< " with " << event.size() << " particles" << endl;
// run the jet clustering with the base jet definition and the
- // IFNPlugin-based jet definition
+ // SDFPlugin-based jet definition
vector<PseudoJet> base_jets = base_jet_def(event);
cout<<"now do the sd..."<<endl;
vector<PseudoJet> sdflav_jets = base_jet_def(event);
sdFlavCalc(sdflav_jets);
// // ----------------------------------------------------
// // loop over the two leading jets and print out their properties
for (unsigned int ijet = 0; ijet < base_jets.size() && ijet < njetmax; ijet++) {
- // first print out the original anti-kt jets and the IFN jets
+ // first print out the original anti-kt jets and the SDF jets
const auto & base_jet = base_jets[ijet];
const auto & sdflav_jet = sdflav_jets [ijet];
cout << endl;
cout << "base jet " << ijet << ": ";
cout << "pt=" << base_jet.pt() << " rap=" << base_jet.rap() << " phi=" << base_jet.phi();
cout << ", flav = " << FlavHistory::current_flavour_of(base_jet).description() << endl;
cout << "SD flav jet " << ijet << ": ";
cout << "pt=" << sdflav_jet.pt() << " rap=" << sdflav_jet.rap() << " phi=" << sdflav_jet.phi();
cout << ", flav = " << FlavHistory::current_flavour_of(sdflav_jet).description() << endl;
}
}
return 0;
}
// read in input particles and set up PseudoJets with flavour information
-void read_event(vector<PseudoJet> &event){
+void read_event(vector<PseudoJet> &event){
// read in the input particles and their PDG IDs
string line;
double px, py, pz, E;
int pdg_id;
event.resize(0);
while(getline(cin,line)) {
if(line[0] == '#') continue;
istringstream iss(line);
iss >> px >> py >> pz >> E >> pdg_id;
// create a fastjet::PseudoJet with these components and put it onto
// back of the input_particles vector
PseudoJet p(px,py,pz,E);
// assign information about flavour (will be deleted automatically)
p.set_user_info(new FlavHistory(pdg_id));
event.push_back(p);
if (cin.peek() == '\n' || cin.peek() == EOF) {
getline(cin,line);
break;
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, May 14, 10:41 AM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5100625
Default Alt Text
(16 KB)

Event Timeline