// main112.cc is a part of the PYTHIA event generator. // Copyright (C) 2017 Torbjorn Sjostrand. // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details. // Please respect the MCnet Guidelines, see GUIDELINES for details. // This test program will generate p-Pb collisions at sqrt(S_NN)=5TeV // using Angantyr model for Heavy Ion collisions. The analysis will // divide the event in centrality classes and measure the charged // pseudo-rapidity distribution in each class in the way described in // the ATLAS analysis in arXiv:1508.00848 [hep-ex]. //http://home.thep.lu.se/Pythia/pythia82html/HeavyIons.html #include "Pythia8/Pythia.h" // ROOT, for saving Pythia events as trees in a file. #include "TTree.h" #include "TFile.h" // You need to include this to get access to the HIInfo object for // HeavyIons. #include "Pythia8/HeavyIons.h" using namespace Pythia8; int main() { Pythia pythia; //Precision: cout< > MapIdx; MapIdx expetaidx, genetaidx; vector expetadist(8), genetadist(8); string expetaname("EtadistCexp"), genetaname("EtadistCgen"); vector expsumw(8, 0.0), gensumw(8, 0.0); for ( int i = 0; i < 8; ++i ) { expetaidx[explim[i]] = i; expetadist[i] = new Hist(expetaname + char('0' + i), 54, -2.7, 2.7); genetaidx[genlim[i]] = i; genetadist[i] = new Hist(genetaname + char('0' + i), 54, -2.7, 2.7); } // Book histogram for the centrality measure. Hist sumet("SumETfwd", 100, 0.0, 200.0); // Also make a map of all weight to check the generated centrality // classes. multimap gencent; // Book a histogram for the distribution of number of wounded // nucleons. Hist wounded("Nwounded", 60, -0.5, 59.5); // Sum up the weights of all generated events. double sumw = 0.0; // Initialise Pythia. pythia.init(); // Set up the ROOT TFile and TTree. TFile *file = TFile::Open("pytHIa.root","recreate"); //TTRee " T " with the variable of the event TTree *T = new TTree("T","Tree"); //TTRee " T1 " number of events TTree *T1 = new TTree("T1","Tree1"); //The Branchs of the TTree "T". T->Branch("px",&px); T->Branch("py",&py); T->Branch("pz",&pz); T->Branch("pt",&pt); T->Branch("e",&e); T->Branch("id",&id); T->Branch("Eta",&Eta); T->Branch("Phi",&Phi); //The Branchs of the TTree "T1". T1->Branch("gama",&gama); T1->Branch("bx",&bx); T1->Branch("by",&by); T1->Branch("bz",&bz); T1->Branch("Nparticles",&Nparticles); // ****************************************************************** // Loop over events. int nEvents = 2; for ( int iEvent = 0; iEvent < nEvents; ++iEvent ) { if ( !pythia.next() ) continue; // First sum up transverse energy for centrality measure and also // check that the trigger requiring ar least one charged particle // forward and backward. double etfwd = 0.0; bool trigfwd = false; bool trigbwd = false; for (int i = 0; i < pythia.event.size(); ++i) { Particle & p = pythia.event[i]; if ( p.isFinal() ) { eta = p.eta(); if ( p.isCharged() && p.pT() > 0.1 && eta < -2.09 && eta > -3.84 ) trigfwd = true; if ( p.isCharged() && p.pT() > 0.1 && eta > 2.09 && eta < 3.84 ) trigbwd = true; if ( p.pT() > 0.1 && eta < -3.2 && eta > -4.9 ) etfwd += p.eT(); //Variables of the particles px = p.px(); py = p.py(); pz = p.pz(); pt = p.pT(); e = p.e(); id = p.id(); Eta = p.eta(); //cout << "Eta = " << Eta << endl; Phi = p.phi(); //total momentum of the particle i somapx = somapx + px; somapy = somapy + py; somapz = somapz + pz; somae = somae + e; //Fill the TTRee "T" T->Fill(); //This count the number of particle in the event. cont++; } //betax, betay, betaz. bx = somapx/somae; by = somapy/somae; bz = somapz/somae; //total moment calculation P = sqrt(pow(somapx,2)+pow(somapy,2)+pow(somapz,2)); //speed parameter: beta = P/somae; //Lorentz Factor gama = pow(1-(beta*beta),-0.5); Nparticles = cont; //Fill the TTRee "T1" T1->Fill(); cont = somae = somapx = somapy = somapz = P = 0; //zerar the variables } // ********************************************************************************* // Write tree. //T->Print(); // Print the screen (terminal) the information about the TTRee T T->Write(); //T1->Print(); // Print the screen (terminal) the information about the TTRee T1 T1->Write(); delete file; // ********************************************************************************* // Skip if not triggered if ( !(trigfwd && trigbwd) ) continue; // Keep track of the sum of waights double weight = pythia.info.weight(); sumw += weight; // Histogram and save the summed Et. sumet.fill(etfwd, weight); gencent.insert(make_pair(etfwd, weight)); // Also fill the number of (absorptively and diffractively) // wounded nucleaons. int nw = pythia.info.hiinfo->nAbsTarg() + pythia.info.hiinfo->nDiffTarg(); wounded.fill(nw, weight); // Find the correct centrality histograms. MapIdx::iterator expit = expetaidx.upper_bound(etfwd); int expidx = expit== expetaidx.end()? -1: expit->second; MapIdx::iterator genit = genetaidx.upper_bound(etfwd); int genidx = genit== genetaidx.end()? -1: genit->second; // Sum the weights in the centrality classes, skip if not in a class. if ( expidx < 0 && genidx < 0 ) continue; if ( expidx >= 0 ) expsumw[expidx] += weight; if ( genidx >= 0 ) gensumw[genidx] += weight; // Go through the event again and fill the eta distributions. for (int i = 0; i < pythia.event.size(); ++i) { Particle & p = pythia.event[i]; if ( p.isFinal() && p.isCharged() && abs(p.eta()) < 2.7 && p.pT() > 0.1 ) { if ( expidx >= 0 ) expetadist[expidx]->fill(p.eta(), weight); if ( genidx >= 0 ) genetadist[genidx]->fill(p.eta(), weight); } } } // The run is over, so we write out some statistics. // Now, we just have to normalize and prtint out the histograms. We // choose to print the histograms to a file that can be read by // eg. gnuplot. ofstream ofs("main112.dat"); sumet /= sumw*2.0; ofs << "# " << sumet.getTitle() << endl; sumet.table(ofs); wounded /= sumw; ofs << "\n# " << wounded.getTitle() << endl; wounded.table(ofs); // Print out the centrality binned eta distributions and delete the // heap-allocate histograms. for ( int idx = 0; idx < 8; ++idx ) { *expetadist[idx] /= expsumw[idx]*0.1; ofs << "\n# " << expetadist[idx]->getTitle() << endl; expetadist[idx]->table(ofs); delete expetadist[idx]; *genetadist[idx] /= gensumw[idx]*0.1; ofs << "\n# " << genetadist[idx]->getTitle() << endl; genetadist[idx]->table(ofs); delete genetadist[idx]; } // Befor we end, we want to check that our generated centrality // classes were the same as we guessed. double curr = 0.0; double prev = 0.0; double acc = 0.0; int idxa = 7; double lim = sumw*(1.0 - pclim[idxa]); vector newlim(8); for ( multimap::iterator it = gencent.begin(); it != gencent.end(); ++it ) { prev = curr; curr = it->first; double w = it->second; if ( acc < lim && acc + w >= lim ) { newlim[idxa--] = prev + (curr - prev)*(lim - acc)/w; lim = sumw*(1.0 - pclim[idxa]); } acc += w; } cout << "The generated limits between centrality classes in this run:\n" << " % assumed actual data\n"; for ( int idx = 0; idx < 8; ++idx ) cout << setw(4) << int(pclim[idx]*100.0 + 0.5) << setw(10) << fixed << setprecision(1) << genlim[idx] << setw(10) << fixed << setprecision(1) << newlim[idx] << setw(10) << fixed << setprecision(1) << explim[idx] << endl; // And we're done! return 0; }