// Example showing usage of JetsWithoutJets classes.
//
// Compile it with "make example" and run it with
//
// ./example < ../data/single-event.dat
//
// Copyright (c) 2013
// Daniele Bertolini and Jesse Thaler
//
// $Id: $
//----------------------------------------------------------------------
// 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
#include
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/JetDefinition.hh"
#include "fastjet/tools/Filter.hh"
#include "JetsWithoutJets.hh" // In external code, this should be fastjet/contrib/JetsWithoutJets.hh
using namespace std;
using namespace fastjet;
using namespace fastjet::contrib;
// forward declaration to make things clearer
void read_event(vector &event);
void analyze(const vector & input_particles);
//----------------------------------------------------------------------
int main(){
//----------------------------------------------------------
// read in input particles
vector event;
read_event(event);
cout << "#########" << endl;
cout << "## Read an event with " << event.size() << " particles" << endl;
//----------------------------------------------------------
// illustrate how this JetsWithoutJets contrib works
analyze(event);
return 0;
}
// read in input particles
void read_event(vector &event){
string line;
while (getline(cin, line)) {
istringstream linestream(line);
// take substrings to avoid problems when there are extra "pollution"
// characters (e.g. line-feed).
if (line.substr(0,4) == "#END") {return;}
if (line.substr(0,1) == "#") {continue;}
double px,py,pz,E;
linestream >> px >> py >> pz >> E;
PseudoJet particle(px,py,pz,E);
// push event onto back of full_event vector
event.push_back(particle);
}
}
// Main code
void analyze(const vector & input_particles) {
// Jet parameters.
double Rjet = 1.0;
double pTcut = 200.0;
// Subjet parameters. Need for trimming.
double Rsub = 0.2;
double fcut = 0.05;
double ptsubcut = 50.0; // additional ptsubcut for subjet multiplicity
//////////
// Basic event shape analysis.
//////////
// Selectors of the type SelectorEventTrimmer are trimmers of the event.
Selector trimmer=SelectorShapeTrimming(Rjet,pTcut,Rsub,fcut);
// Classes derived from JetLikeEventShape take as input a vector
// representing the event, and return a number.
// They have two constructors: you can specify Rjet and pTcut solely or
// in addition to those also Rsub and fcut (if you want to implement
// built-in trimming at the same time).
// N.B.: trimming an event and then calculating the event shape is NOT
// the same as calculating the trimmed event shape. See the README for
// more information.
// ShapeJetMultiplicity = jet counting
ShapeJetMultiplicity Nj(Rjet,pTcut);
ShapeJetMultiplicity Nj_trim(Rjet,pTcut,Rsub,fcut); // with trimming
// ShapeScalarPt = HT (summed jet pT)
ShapeScalarPt HT(Rjet,pTcut);
ShapeScalarPt HT_trim(Rjet,pTcut,Rsub,fcut); // with trimming
// ShapeMissingPt = missing pT
ShapeMissingPt HTmiss(Rjet,pTcut);
ShapeMissingPt HTmiss_trim(Rjet,pTcut,Rsub,fcut); // with trimming
cout << setprecision(6);
cout << "#########" << endl;
cout << "## Example of basic event shape analysis" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << ", pTcut=" << pTcut < ptval = Nj_allPt.ptCutArray();
std::vector NjPtval = Nj_allPt.eventShapeArray();
//////////
// Variable R analysis.
//////////
// These use the class ShapeJetMultiplicity_VariableR (at present there is no
// general class for variable R observables because of the high computational time).
// Here, the full R information is kept.
ShapeJetMultiplicity_VariableR Nj_allR(pTcut);
ShapeJetMultiplicity_VariableR Nj_allR_trim(pTcut,Rsub,fcut); // with trimming
Nj_allR.set_input(input_particles);
Nj_allR_trim.set_input(input_particles);
cout << "#########" << endl;
cout << "## Example of variable R analysis" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << " (unless otherwise stated), pTcut=" << pTcut < myShapes;
vector myNames;
myShapes.push_back( new ShapeJetMultiplicity(Rjet,pTcut) );
myNames.push_back( "Njet");
myShapes.push_back( new ShapeJetMultiplicity(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "Njet_trim");
myShapes.push_back( new ShapeScalarPt(Rjet,pTcut) );
myNames.push_back( "HT");
myShapes.push_back( new ShapeScalarPt(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "HT_trim");
myShapes.push_back( new ShapeMissingPt(Rjet,pTcut) );
myNames.push_back( "MissHT");
myShapes.push_back( new ShapeMissingPt(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "MissHT_trim");
myShapes.push_back( new ShapeSummedMass(Rjet,pTcut) );
myNames.push_back( "SigmaM");
myShapes.push_back( new ShapeSummedMass(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "SigmaM_trim");
myShapes.push_back( new ShapeSummedMassSquared(Rjet,pTcut) );
myNames.push_back( "SigmaM2");
myShapes.push_back( new ShapeSummedMassSquared(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "SigmaM2_trim");
myShapes.push_back( new ShapeTrimmedSubjetMultiplicity(Rjet,pTcut,Rsub,fcut,ptsubcut) ); //with trimming
myNames.push_back( "SigmaNsub_trim");
for (int n = -2; n <= 2; n++) {
myShapes.push_back( new ShapeScalarPtToN(n,Rjet,pTcut) );
myShapes.push_back( new ShapeScalarPtToN(n,Rjet,pTcut,Rsub,fcut) ); //with trimming
stringstream myStream;
myStream << "GenHT_" << n;
myNames.push_back( myStream.str());
myNames.push_back( myStream.str() + "_trim");
}
// outputing the variables
cout << "#########" << endl;
cout << "## Examples showing more general shapes" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << ", pTcut=" << pTcut << endl;
cout << "Trimming parameters: R_sub=" << Rsub << ", fcut=" << fcut << endl;
cout << "#####" << endl;
for (unsigned int i = 0; i < myShapes.size(); i++) {
cout << myShapes.at(i)->description() << endl; // ideally each even shape should have a description
myShapes.at(i)->setUseStorageArray(false);
double valueNoStorage = myShapes.at(i)->result(input_particles);
myShapes.at(i)->setUseStorageArray(true);
double valueYesStorage = myShapes.at(i)->result(input_particles);
cout << myNames.at(i) << "="
<< valueNoStorage << endl;
cout << "(Storage array works? " << (valueNoStorage == valueYesStorage ? "Yes" : "No!!") << ")" << endl;
cout << "#" << endl;
delete myShapes.at(i);
}
cout << "#####" << endl;
// timing tests for the developers
double do_timing_test = false;
if (do_timing_test) {
clock_t clock_begin, clock_end;
double num_iter;
cout << setprecision(6);
num_iter = 1000;
clock_begin = clock();
ShapeScalarPt NjetA(Rjet,pTcut);
cout << "timing " << NjetA.description() << endl;
for (int t = 0; t < num_iter; t++) {
NjetA(input_particles);
}
clock_end = clock();
cout << "Method A: " << (clock_end-clock_begin)/double(CLOCKS_PER_SEC*num_iter)*1000 << " ms per Njet"<< endl;
num_iter = 1000;
clock_begin = clock();
JetLikeEventShape NjetB(new FunctorJetScalarPt(),Rjet,pTcut);
NjetB.setUseStorageArray(false);
cout << "timing " << NjetB.description() << endl;
for (int t = 0; t < num_iter; t++) {
NjetB(input_particles);
}
clock_end = clock();
cout << "Method B: " << (clock_end-clock_begin)/double(CLOCKS_PER_SEC*num_iter)*1000 << " ms per Njet"<< endl;
}
}