// To run this example, use the following command: // // ./example-CMP < ../data/pythia8_Zq_vshort.dat // // NB: the example file reads in a file with 6 light flavours // (though for this algorithm we need to strip off all but one), and // an extra high density of quarks, to help with "make check" // test things more thoroughly //---------------------------------------------------------------------- // $Id$ // // Copyright (c) 2024, Michal Czakon, Alexander Mitov, and Rene Poncelet // // based on initial version by Fabrizio Caola, Radoslaw Grabarczyk, // Maxwell Hutt, Gavin P. Salam, Ludovic Scyboz, and Jesse Thaler // //---------------------------------------------------------------------- // 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 #include "fastjet/PseudoJet.hh" #include "fastjet/contrib/CMPPlugin.hh" using namespace std; using namespace fastjet; using namespace fastjet::contrib; // forward declaration to make things clearer void read_event(vector &event); //---------------------------------------------------------------------- int main(int iargc, char **argv){ // give user control over printout (mainly relevant for make check) // usage: "./example [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(); // we start with a base jet definition (here antikt) double R = 0.4; JetDefinition base_jet_def(antikt_algorithm, R); // enable it to track flavours (default is net flavour) FlavRecombiner flav_recombiner; base_jet_def.set_recombiner(&flav_recombiner); // CMP parameters: // CMP 'a' parameter in // kappa_ij = 1/a * (kT_i^2 + kT_j^2) / (2*kT_max^2) double CMP_a = 0.1; // correction to original CMP algo: do not change this if you want IRC safety! CMPPlugin::CorrectionType CMP_corr = CMPPlugin::CorrectionType::SqrtCoshyCosPhiArgument_a2; // Dynamic definition of ktmax CMPPlugin::ClusteringType CMP_clust = CMPPlugin::ClusteringType::DynamicKtMax; // CMP plugin JetDefinition CMP_jet_def(new CMPPlugin(R, CMP_a, CMP_corr, CMP_clust)); // enable it to track flavours (default is net flavour) CMP_jet_def.set_recombiner(&flav_recombiner); CMP_jet_def.delete_plugin_when_unused(); cout << "! this analysis considers only b-flavour from input events !" << endl; cout << "base jet definition: " << base_jet_def.description() << endl; cout << "CMP jet definition: " << CMP_jet_def.description() << endl; // loop over some number of events unsigned int n_events = 10; for (unsigned int iev = 0; iev < n_events && iev < nevmax; iev++) { // read in input particles: see that routine for info // on how to set up the PseudoJets with flavour information vector event; read_event(event); cout << "\n#---------------------------------------------------------------\n"; cout << "# read event " << iev << " with " << event.size() << " particles" << endl; // run the jet clustering with the base jet definition and the // CMPPlugin-based jet definition vector base_jets = base_jet_def(event); vector CMP_jets = CMP_jet_def(event); // ---------------------------------------------------- // 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 const auto & base_jet = base_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; // for the first event, print out the jet constituents' pt and initial and final flavours cout << "constituents:" << endl; for (const auto & c: sorted_by_pt(base_jet.constituents())) { cout << " pt = " << setw(10) << c.pt(); cout << ", orig. flav = " << setw(8) << FlavHistory::initial_flavour_of(c).description(); cout << ", final flav = " << setw(8) << FlavHistory::current_flavour_of(c).description(); cout << endl; } } // ---------------------------------------------------- // loop over the two leading jets and print out their properties for (unsigned int ijet = 0; ijet < CMP_jets.size() && ijet < njetmax; ijet++) { // and the CMP jets const auto & CMP_jet = CMP_jets [ijet]; cout << endl; cout << "CMP jet " << ijet << ": "; cout << "pt=" << CMP_jet.pt() << " rap=" << CMP_jet.rap() << " phi=" << CMP_jet.phi(); cout << ", flav = " << FlavHistory::current_flavour_of(CMP_jet).description() << endl; // for the first event, print out the jet constituents' pt and initial and final flavours cout << "constituents:" << endl; for (const auto & c: sorted_by_pt(CMP_jet.constituents())) { cout << " pt = " << setw(10) << c.pt(); cout << ", orig. flav = " << setw(8) << FlavHistory::initial_flavour_of(c).description(); cout << ", final flav = " << setw(8) << FlavHistory::current_flavour_of(c).description(); cout << endl; } } } return 0; } // read in input particles and set up PseudoJets with flavour information void read_event(vector &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) FlavInfo flav_info_init(pdg_id); // we take only b-quarks flav_info_init.reset_all_but_flav(5); // need to cast to const for constructor p.set_user_info(new FlavHistory(const_cast(flav_info_init))); event.push_back(p); if (cin.peek() == '\n' || cin.peek() == EOF) { getline(cin,line); break; } } }