StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
main72.cc
1 // main72.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2014 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // This is a simple test program.
7 // It compares SlowJet, FJcore and FastJet, showing that they
8 // find the same jets.
9 
10 #include "Pythia8/Pythia.h"
11 
12 // The FastJet3.h header enables automatic initialisation of
13 // fastjet::PseudoJet objects from Pythia8 Particle and Vec4 objects,
14 // as well as advanced features such as access to (a copy of)
15 // the original Pythia 8 Particle directly from the PseudoJet,
16 // and fastjet selectors that make use of the Particle properties.
17 // See the extensive comments in the header file for further details
18 // and examples.
19 #include "Pythia8/FastJet3.h"
20 
21 using namespace Pythia8;
22 
23 int main() {
24 
25  // Number of events, generated and listed ones (for jets).
26  int nEvent = 1000;
27  int nListJets = 3;
28 
29  // Select common parameters for SlowJet and FastJet analyses.
30  int power = -1; // -1 = anti-kT; 0 = C/A; 1 = kT.
31  double R = 0.7; // Jet size.
32  double pTMin = 5.0; // Min jet pT.
33  double etaMax = 5.0; // Pseudorapidity range of detector.
34  int select = 2; // Which particles are included?
35  int massSet = 2; // Which mass are they assumed to have?
36 
37  // Generator. Shorthand for event.
38  Pythia pythia;
39  Event& event = pythia.event;
40 
41  // Process selection.
42  pythia.readString("HardQCD:all = on");
43  pythia.readString("PhaseSpace:pTHatMin = 200.");
44 
45  // No event record printout.
46  pythia.readString("Next:numberShowInfo = 0");
47  pythia.readString("Next:numberShowProcess = 0");
48  pythia.readString("Next:numberShowEvent = 0");
49 
50  // LHC initialization.
51  pythia.readString("Beams:eCM = 14000.");
52  pythia.init();
53 
54  // Set up SlowJet jet finder in native mode.
55  SlowJet slowJet( power, R, pTMin, etaMax, select, massSet, 0, false);
56 
57  // Set up SlowJet jet finder as a wrapper to the fjcore package.
58  // Note that this is now the default SlowJet constructor choice.
59  SlowJet fjCore( power, R, pTMin, etaMax, select, massSet, 0, true);
60 
61  // Set up FastJet jet finder.
62  // one can use either explicitly use antikt, cambridge, etc., or
63  // just use genkt_algorithm with specification of power
64  //fastjet::JetAlgorithm algorithm;
65  //if (power == -1) algorithm = fastjet::antikt_algorithm;
66  //if (power == 0) algorithm = fastjet::cambridge_algorithm;
67  //if (power == 1) algorithm = fastjet::kt_algorithm;
68  //fastjet::JetDefinition jetDef(algorithm, R);
69  // there's no need for a pointer to the jetDef (it's a fairly small object)
70  fastjet::JetDefinition jetDef(fastjet::genkt_algorithm, R, power);
71  std::vector <fastjet::PseudoJet> fjInputs;
72 
73  // Histograms.
74  Hist nJetsS("number of jets (SlowJet)", 100, -0.5, 99.5);
75  Hist nJetsC("number of jets, FJcore - SlowJet ", 99, -49.5, 49.5);
76  Hist nJetsF("number of jets, FastJet - SlowJet", 99, -49.5, 49.5);
77  Hist pTjetsS("pT for jets (SlowJet)", 100, 0., 500.);
78  Hist pTjetsC("pT for jets, FJcore - SlowJet ", 100, -10., 10.);
79  Hist pTjetsF("pT for jets, FastJet - SlowJet", 100, -10., 10.);
80  Hist etaJetsS("eta for jets (SlowJet)", 100, -5., 5.);
81  Hist phiJetsS("phi for jets (SlowJet)", 100, -M_PI, M_PI);
82  Hist RdistC("R distance FJcore to SlowJet ", 100, 0., 1.);
83  Hist RdistF("R distance FastJet to SlowJet", 100, 0., 1.);
84  Hist distJets("R distance between jets", 100, 0., 10.);
85  Hist pTdiff("pT difference between consecutive jets", 100, -100., 400.);
86  Hist nAna("multiplicity of analyzed event", 100, -0.5, 999.5);
87  Hist tGen("generation time as fn of multiplicity", 100, -0.5, 999.5);
88  Hist tSlow("SlowJet time as fn of multiplicity", 100, -0.5, 999.5);
89  Hist tCore("FJcore time as fn of multiplicity ", 100, -0.5, 999.5);
90  Hist tFast("FastJet time as fn of multiplicity", 100, -0.5, 999.5);
91  Hist tSlowGen("SlowJet/generation time as fn of multiplicity",
92  100, -0.5, 999.5);
93  Hist tCoreGen("FJcore/generation time as fn of multiplicity",
94  100, -0.5, 999.5);
95  Hist tFastGen("FastJet/generation time as fn of multiplicity",
96  100, -0.5, 999.5);
97  Hist tFastCore("FastJet/FJcore time as fn of multiplicity",
98  100, -0.5, 999.5);
99 
100  // Begin event loop. Generate event. Skip if error.
101  for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
102  clock_t befGen = clock();
103  if (!pythia.next()) continue;
104  clock_t aftGen = clock();
105 
106  // Begin SlowJet analysis of jet properties. List first few.
107  clock_t befSlow = clock();
108  slowJet.analyze( pythia.event );
109  clock_t aftSlow = clock();
110  if (iEvent < nListJets) slowJet.list();
111 
112  // Fill inclusive SlowJet jet distributions.
113  int nSlow = slowJet.sizeJet();
114  nJetsS.fill( nSlow );
115  for (int i = 0; i < nSlow; ++i) {
116  pTjetsS.fill( slowJet.pT(i) );
117  etaJetsS.fill( slowJet.y(i) );
118  phiJetsS.fill( slowJet.phi(i) );
119  }
120 
121  // Fill distance between SlowJet jets.
122  for (int i = 0; i < nSlow - 1; ++i)
123  for (int j = i + 1; j < nSlow; ++j) {
124  double dY = slowJet.y(i) - slowJet.y(j);
125  double dPhi = abs( slowJet.phi(i) - slowJet.phi(j) );
126  if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
127  double dR = sqrt( pow2(dY) + pow2(dPhi) );
128  distJets.fill( dR );
129  }
130 
131  // Fill pT-difference between SlowJet jets (to check ordering of list).
132  for (int i = 1; i < nSlow; ++i)
133  pTdiff.fill( slowJet.pT(i-1)- slowJet.pT(i) );
134 
135  // Begin FJcore analysis of jet properties. List first few.
136  clock_t befCore = clock();
137  fjCore.analyze( pythia.event );
138  clock_t aftCore = clock();
139  if (iEvent < nListJets) fjCore.list();
140 
141  // Fill distribution of fjCore jets relative to SlowJet ones.
142  int nCore = fjCore.sizeJet();
143  nJetsC.fill( nCore - nSlow);
144  if (nCore == nSlow) {
145  for (int i = 0; i < nCore; ++i) {
146  pTjetsC.fill( fjCore.pT(i) - slowJet.pT(i) );
147  double dist2 = pow2( fjCore.y(i) - slowJet.y(i))
148  + pow2( fjCore.phi(i) - slowJet.phi(i) );
149  RdistC.fill( sqrt(dist2) );
150  }
151  }
152 
153  // Begin FastJet analysis: extract particles from event record.
154  clock_t befFast = clock();
155  fjInputs.resize(0);
156  Vec4 pTemp;
157  double mTemp;
158  int nAnalyze = 0;
159  for (int i = 0; i < event.size(); ++i) if (event[i].isFinal()) {
160 
161  // Require visible/charged particles inside detector.
162  if (select > 2 && event[i].isNeutral() ) continue;
163  else if (select == 2 && !event[i].isVisible() ) continue;
164  if (etaMax < 20. && abs(event[i].eta()) > etaMax) continue;
165 
166  // Create a PseudoJet from the complete Pythia particle.
167  fastjet::PseudoJet particleTemp = event[i];
168 
169  // Optionally modify mass and energy.
170  pTemp = event[i].p();
171  mTemp = event[i].m();
172  if (massSet < 2) {
173  mTemp = (massSet == 0 || event[i].id() == 22) ? 0. : 0.13957;
174  pTemp.e( sqrt(pTemp.pAbs2() + mTemp*mTemp) );
175  particleTemp.reset_momentum( pTemp.px(), pTemp.py(),
176  pTemp.pz(), pTemp.e() );
177  }
178 
179  // Store acceptable particles as input to Fastjet.
180  // Conversion to PseudoJet is performed automatically
181  // with the help of the code in FastJet3.h.
182  fjInputs.push_back( particleTemp);
183  ++nAnalyze;
184  }
185 
186  // Run Fastjet algorithm and sort jets in pT order.
187  vector <fastjet::PseudoJet> inclusiveJets, sortedJets;
188  fastjet::ClusterSequence clustSeq(fjInputs, jetDef);
189  inclusiveJets = clustSeq.inclusive_jets(pTMin);
190  sortedJets = sorted_by_pt(inclusiveJets);
191  clock_t aftFast = clock();
192 
193  // List first few FastJet jets and some info about them.
194  // Note: the final few columns are illustrative of what information
195  // can be extracted, but does not exhaust the possibilities.
196  if (iEvent < nListJets) {
197  cout << "\n -------- FastJet jets, p = " << setw(2) << power
198  << " --------------------------------------------------\n\n "
199  << " i pT y phi mult chgmult photons"
200  << " hardest pT in neutral " << endl
201  << " "
202  << " constituent hadrons " << endl;
203  for (int i = 0; i < int(sortedJets.size()); ++i) {
204  vector<fastjet::PseudoJet> constituents
205  = sortedJets[i].constituents();
206  fastjet::PseudoJet hardest
207  = fastjet::SelectorNHardest(1)(constituents)[0];
208  vector<fastjet::PseudoJet> neutral_hadrons
209  = ( fastjet::SelectorIsHadron()
210  && fastjet::SelectorIsNeutral())(constituents);
211  double neutral_hadrons_pt = join(neutral_hadrons).perp();
212  cout << setw(4) << i << fixed << setprecision(3) << setw(11)
213  << sortedJets[i].perp() << setw(9) << sortedJets[i].rap()
214  << setw(9) << sortedJets[i].phi_std()
215  << setw(6) << constituents.size()
216  << setw(8) << fastjet::SelectorIsCharged().count(constituents)
217  << setw(8) << fastjet::SelectorId(22).count(constituents)
218  << setw(13) << hardest.user_info<Particle>().name()
219  << " " << setw(10) << neutral_hadrons_pt << endl;
220  }
221  cout << "\n -------- End FastJet Listing ------------------"
222  << "---------------------------------" << endl;
223  }
224 
225  // Fill distribution of FastJet jets relative to SlowJet ones.
226  int nFast = sortedJets.size();
227  nJetsF.fill( nFast - nSlow);
228  if (nFast == nSlow) {
229  for (int i = 0; i < nFast; ++i) {
230  pTjetsF.fill( sortedJets[i].perp() - slowJet.pT(i) );
231  double dist2 = pow2( sortedJets[i].rap() - slowJet.y(i))
232  + pow2( sortedJets[i].phi_std() - slowJet.phi(i));
233  RdistF.fill( sqrt(dist2) );
234  }
235  }
236 
237  // Comparison of time consumption by analyzed multiplicity.
238  nAna.fill( nAnalyze);
239  tGen.fill( nAnalyze, aftGen - befGen);
240  tSlow.fill( nAnalyze, aftSlow - befSlow);
241  tCore.fill( nAnalyze, aftCore - befCore);
242  tFast.fill( nAnalyze, aftFast - befFast);
243 
244  // End of event loop.
245  }
246 
247  // Statistics. Histograms.
248  pythia.stat();
249  tSlowGen = tSlow / tGen;
250  tCoreGen = tCore / tGen;
251  tFastGen = tFast / tGen;
252  tFastCore = tFast / tCore;
253  tGen /= nAna;
254  tSlow /= nAna;
255  tCore /= nAna;
256  tFast /= nAna;
257  cout << nJetsS << nJetsC << nJetsF << pTjetsS << pTjetsC << pTjetsF
258  << etaJetsS << phiJetsS << RdistC << RdistF << distJets << pTdiff
259  << nAna << tGen << tSlow << tCore << tFast << tSlowGen << tCoreGen
260  << tFastGen << tFastCore;
261 
262  // Done.
263  return 0;
264 }