/* * Delphes: a framework for fast simulation of a generic collider experiment * Copyright (C) 2012-2014 Universite catholique de Louvain (UCL), Belgium * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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 program. If not, see . */ /* ######################################################################## This simple example shows how to use Delphes with an external FastJet installation. Events are specified via the multidimensional array "EVENTS" (for an example reading an HepMC file see ExternalFastJetHepMC.cpp). In order to run this example you first need to set the paths to your Delphes, FastJet and ROOT installations (DELPHES_DIR, FASTJET_DIR and ROOT_DIR): DELPHES_DIR= FASTJET_DIR= ROOT_DIR= Then run the following commands to build the executable: DELPHES_LIB="-Wl,-rpath,$DELPHES_DIR -L$DELPHES_DIR -lDelphesNoFastJet" FASTJET_INC=`$FASTJET_DIR/bin/fastjet-config --cxxflags` FASTJET_LIB=`$FASTJET_DIR/bin/fastjet-config --libs` ROOT_INC=`$ROOT_DIR/bin/root-config --incdir` ROOT_LIB=`$ROOT_DIR/bin/root-config --libs` CXXFLAGS="$FASTJET_INC -I$ROOT_INC -I$DELPHES_DIR -I$DELPHES_DIR/external" LDFLAGS="$FASTJET_LIB $ROOT_LIB -lEG $DELPHES_LIB" g++ $CXXFLAGS examples/ExternalFastJet/ExternalFastJetBasic.cpp $LDFLAGS -o ExternalFastJetBasic Then run: ./ExternalFastJetBasic cards/delphes_card_CMS_NoFastJet.tcl ######################################################################## */ #include #include #include #include #include "TROOT.h" #include "TApplication.h" #include "TFile.h" #include "TObjArray.h" #include "TDatabasePDG.h" #include "TParticlePDG.h" #include "TLorentzVector.h" #include "modules/Delphes.h" #include "classes/DelphesClasses.h" #include "classes/DelphesFactory.h" #include "ExRootAnalysis/ExRootTreeWriter.h" #include "ExRootAnalysis/ExRootTreeBranch.h" #include "ExRootAnalysis/ExRootProgressBar.h" #include "fastjet/PseudoJet.hh" #include "fastjet/JetDefinition.hh" #include "fastjet/ClusterSequence.hh" using namespace std; using namespace fastjet; //--------------------------------------------------------------------------- const int NEVENTS = 2; const int NPARTICLES = 4; float EVENTS[NEVENTS][NPARTICLES][11] = { { {-211, 1, -2.91e-01, 1.99e-01, -1.30e+00, 1.35e+00, 1.3957e-01, 0.0, 0.0, 0.0, 0.0}, { 211, 1, -2.62e-02, 1.90e-01, 1.42e+00, 1.44e+00, 1.3957e-01, 0.0, 0.0, 0.0, 0.0}, {-211, 1, -3.08e-02, -2.30e-01, 5.13e+00, 5.14e+00, 1.3957e-01, 0.0, 0.0, 0.0, 0.0}, { 211, 1, 1.21e-01, -3.52e-01, 2.12e+01, 2.12e+01, 1.3957e-01, 0.0, 0.0, 0.0, 0.0} }, { {22, 1, -7.80e-02, -9.70e-02, 2.03e+01, 2.03e+01, 0.0, 0.0, 0.0, 0.0, 0.0}, {22, 1, -1.16e-02, -2.08e-02, 4.89e-01, 4.90e-01, 0.0, 0.0, 0.0, 0.0, 0.0}, {22, 1, 5.64e-02, -1.34e-02, 5.81e+00, 5.82e+00, 0.0, 0.0, 0.0, 0.0, 0.0}, {22, 1, 2.35e-01, -1.04e-01, 9.12e+00, 9.12e+00, 0.0, 0.0, 0.0, 0.0, 0.0} } }; //--------------------------------------------------------------------------- // this function converts input event array into Delphes candidates (defined below) void ConvertInput(Int_t event, DelphesFactory *factory, TObjArray *allParticleOutputArray, TObjArray *stableParticleOutputArray, TObjArray *partonOutputArray); //---------------------------------------------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { // Declaration of variables ExRootConfReader *confReader = 0; Delphes *modularDelphes = 0; DelphesFactory *factory = 0; TObjArray *allParticleOutputArray = 0; TObjArray *stableParticleOutputArray = 0; TObjArray *partonOutputArray = 0; Int_t event; TObjArray *inputArray = 0; TIterator *inputIterator = 0; Candidate *candidate = 0; TLorentzVector momentum; JetDefinition *definition = 0; vector inputList, outputList; PseudoJet jet; gROOT->SetBatch(); int appargc = 1; char appName[] = "ExternalFastJetBasic"; char *appargv[] = {appName}; TApplication app(appName, &appargc, appargv); if(argc != 2) { cout << " Usage: " << appName << " config_file" << endl; cout << " config_file - configuration file in Tcl format." << endl; return 1; } try { // Initialization confReader = new ExRootConfReader; confReader->ReadFile(argv[1]); modularDelphes = new Delphes("Delphes"); modularDelphes->SetConfReader(confReader); factory = modularDelphes->GetFactory(); allParticleOutputArray = modularDelphes->ExportArray("allParticles"); stableParticleOutputArray = modularDelphes->ExportArray("stableParticles"); partonOutputArray = modularDelphes->ExportArray("partons"); modularDelphes->InitTask(); // fastjet definition ClusterSequence::print_banner(); definition = new JetDefinition(antikt_algorithm, 0.5); // Define your input candidates to fastjet (by default particle-flow objects). // If you want pure calorimeter towers change "EFlowMerger/eflow" into "Calorimeter/towers": inputArray = modularDelphes->ImportArray("EFlowMerger/eflow"); inputIterator = inputArray->MakeIterator(); // Event loop for(event = 0; event < NEVENTS; ++event) { modularDelphes->Clear(); // convert EVENT input array into Delphes internal format ConvertInput(event, factory, allParticleOutputArray, stableParticleOutputArray, partonOutputArray); // run Delphes reconstruction modularDelphes->ProcessTask(); inputList.clear(); inputIterator->Reset(); // pass delphes candidates to fastjet clustering while((candidate = static_cast(inputIterator->Next()))) { momentum = candidate->Momentum; jet = PseudoJet(momentum.Px(), momentum.Py(), momentum.Pz(), momentum.E()); inputList.push_back(jet); } // run clustering ClusterSequence sequence(inputList, *definition); outputList.clear(); outputList = sorted_by_pt(sequence.inclusive_jets(0.0)); // tell the user what was done // - the description of the algorithm used // - show the inclusive jets as // {index, rapidity, phi, pt} //---------------------------------------------------------- cout << "Ran " << definition->description() << endl; // label the columns printf("%5s %15s %15s %15s\n","jet #", "rapidity", "phi", "pt"); // print out the details for each jet for (unsigned int i = 0; i < outputList.size(); i++) { printf("%5u %15.8f %15.8f %15.8f\n", i, outputList[i].rap(), outputList[i].phi(), outputList[i].perp()); } } // Finalization modularDelphes->FinishTask(); delete modularDelphes; delete confReader; return 0; } catch(runtime_error &e) { cerr << "** ERROR: " << e.what() << endl; return 1; } } // ------------------------------------------------------------------------------------------------------------------------------------ void ConvertInput(Int_t event, DelphesFactory *factory, TObjArray *allParticleOutputArray, TObjArray *stableParticleOutputArray, TObjArray *partonOutputArray) { Int_t particle; Candidate *candidate; TDatabasePDG *pdg; TParticlePDG *pdgParticle; Int_t pdgCode; Int_t pid, status; Double_t px, py, pz, e, mass; Double_t x, y, z, t; pdg = TDatabasePDG::Instance(); for(particle = 0; particle < NPARTICLES; ++particle) { pid = EVENTS[event][particle][0]; status = EVENTS[event][particle][1]; px = EVENTS[event][particle][2]; py = EVENTS[event][particle][3]; pz = EVENTS[event][particle][4]; e = EVENTS[event][particle][5]; mass = EVENTS[event][particle][6]; x = EVENTS[event][particle][7]; y = EVENTS[event][particle][8]; z = EVENTS[event][particle][9]; t = EVENTS[event][particle][10]; candidate = factory->NewCandidate(); candidate->PID = pid; pdgCode = TMath::Abs(candidate->PID); candidate->Status = status; pdgParticle = pdg->GetParticle(pid); candidate->Charge = pdgParticle ? Int_t(pdgParticle->Charge()/3.0) : -999; candidate->Mass = mass; candidate->Momentum.SetPxPyPzE(px, py, pz, e); candidate->Position.SetXYZT(x, y, z, t); allParticleOutputArray->Add(candidate); if(!pdgParticle) return; if(status == 1) { stableParticleOutputArray->Add(candidate); } else if(pdgCode <= 5 || pdgCode == 21 || pdgCode == 15) { partonOutputArray->Add(candidate); } } }