1 | /***********************************************************************
|
---|
2 | ** **
|
---|
3 | ** /----------------------------------------------\ **
|
---|
4 | ** | Delphes, a framework for the fast simulation | **
|
---|
5 | ** | of a generic collider experiment | **
|
---|
6 | ** \----------------------------------------------/ **
|
---|
7 | ** **
|
---|
8 | ** **
|
---|
9 | ** This package uses: **
|
---|
10 | ** ------------------ **
|
---|
11 | ** FastJet algorithm: Phys. Lett. B641 (2006) [hep-ph/0512210] **
|
---|
12 | ** Hector: JINST 2:P09005 (2007) [physics.acc-ph:0707.1198v2] **
|
---|
13 | ** FROG: [hep-ex/0901.2718v1] **
|
---|
14 | ** **
|
---|
15 | ** ------------------------------------------------------------------ **
|
---|
16 | ** **
|
---|
17 | ** Main authors: **
|
---|
18 | ** ------------- **
|
---|
19 | ** **
|
---|
20 | ** Severine Ovyn Xavier Rouby **
|
---|
21 | ** severine.ovyn@uclouvain.be xavier.rouby@cern **
|
---|
22 | ** **
|
---|
23 | ** Center for Particle Physics and Phenomenology (CP3) **
|
---|
24 | ** Universite catholique de Louvain (UCL) **
|
---|
25 | ** Louvain-la-Neuve, Belgium **
|
---|
26 | ** **
|
---|
27 | ** Copyright (C) 2008-2009, **
|
---|
28 | ** All rights reserved. **
|
---|
29 | ** **
|
---|
30 | ***********************************************************************/
|
---|
31 |
|
---|
32 |
|
---|
33 | #include <iostream>
|
---|
34 | #include <fstream>
|
---|
35 | #include "TLorentzVector.h"
|
---|
36 | #include "BlockClasses.h"
|
---|
37 |
|
---|
38 | #include "PdgParticle.h"
|
---|
39 | #include "ExRootTreeWriter.h"
|
---|
40 | #include "ExRootTreeBranch.h"
|
---|
41 | #include "HepMCConverter.h"
|
---|
42 |
|
---|
43 | #include "GenParticle.h"
|
---|
44 | #include "GenVertex.h"
|
---|
45 | #include "IO_Ascii.h"
|
---|
46 | #include "IO_GenEvent.h"
|
---|
47 |
|
---|
48 | //-------------------------------------------------------------------------
|
---|
49 | int HepMCConverter::find_in_map( const std::map<HepMC::GenParticle*,int>& m, HepMC::GenParticle *p) const
|
---|
50 | {
|
---|
51 | std::map<HepMC::GenParticle*,int>::const_iterator iter = m.find(p);
|
---|
52 | return (iter == m.end()) ? 0 : iter->second;
|
---|
53 | }
|
---|
54 |
|
---|
55 | //--------------------------------------------------------------------------
|
---|
56 | void HepMCConverter::ReadStats()
|
---|
57 | {
|
---|
58 |
|
---|
59 | unsigned int particle_counter=0;
|
---|
60 | index_to_particle.reserve(evt->particles_size());
|
---|
61 | index_to_particle[0] = 0;
|
---|
62 | HepMC::GenEvent::vertex_const_iterator v;
|
---|
63 | for (v = evt->vertices_begin(); v != evt->vertices_end(); ++v )
|
---|
64 | {
|
---|
65 | // making a list of incoming particles of the vertices
|
---|
66 | // so that the mother indices in HEPEVT can be filled properly
|
---|
67 | HepMC::GenVertex::particles_out_const_iterator p1;
|
---|
68 | for (p1 = (*v)->particles_in_const_begin();p1 != (*v)->particles_in_const_end(); ++p1 )
|
---|
69 | {
|
---|
70 |
|
---|
71 | ++particle_counter;
|
---|
72 | //particle_counter can be very large for heavy ions
|
---|
73 | if(particle_counter >= index_to_particle.size() )
|
---|
74 | {
|
---|
75 | //make it large enough to hold up to this index
|
---|
76 | index_to_particle.resize(particle_counter+1);
|
---|
77 | }
|
---|
78 | index_to_particle[particle_counter] = *p1;
|
---|
79 | particle_to_index[*p1] = particle_counter;
|
---|
80 | }
|
---|
81 | // daughters are entered only if they aren't a mother of
|
---|
82 | // another vertex
|
---|
83 | HepMC::GenVertex::particles_out_const_iterator p2;
|
---|
84 | for (p2 = (*v)->particles_out_const_begin();p2 != (*v)->particles_out_const_end(); ++p2)
|
---|
85 | {
|
---|
86 | if (!(*p2)->end_vertex())
|
---|
87 | {
|
---|
88 | ++particle_counter;
|
---|
89 | //particle_counter can be very large for heavy ions
|
---|
90 | if(particle_counter >= index_to_particle.size() )
|
---|
91 | {
|
---|
92 | //make it large enough to hold up to this index
|
---|
93 | index_to_particle.resize(particle_counter+1);
|
---|
94 | }
|
---|
95 | index_to_particle[particle_counter] = *p2;
|
---|
96 | particle_to_index[*p2] = particle_counter;
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | }
|
---|
101 | }
|
---|
102 |
|
---|
103 |
|
---|
104 | //-------------------------------------------------------------------------
|
---|
105 | void HepMCConverter::getStatsFromTuple(int &mo1, int &mo2, int &da1, int &da2, int &status, int &pid, int j) const
|
---|
106 | {
|
---|
107 | if (!evt)
|
---|
108 | {
|
---|
109 | cout << "HepMCFileReader: Got no event :-( Game over already ?" <<endl;
|
---|
110 | }
|
---|
111 | else
|
---|
112 | {
|
---|
113 | status = index_to_particle[j]->status();
|
---|
114 | pid = index_to_particle[j]->pdg_id();
|
---|
115 | if ( index_to_particle[j]->production_vertex() )
|
---|
116 | {
|
---|
117 | int num_mothers = index_to_particle[j]->production_vertex()->particles_in_size();
|
---|
118 | if (num_mothers ==0) {
|
---|
119 | mo1 = 0;
|
---|
120 | mo2 = 0;
|
---|
121 | }
|
---|
122 | else {
|
---|
123 | int first_mother = find_in_map( particle_to_index,*(index_to_particle[j]->production_vertex()->particles_in_const_begin()));
|
---|
124 | int last_mother = first_mother + num_mothers - 1;
|
---|
125 | if ( first_mother == 0 ) last_mother = 0;
|
---|
126 | mo1=first_mother;
|
---|
127 | mo2=last_mother;
|
---|
128 | } // if num_mothers !=0
|
---|
129 | }
|
---|
130 | else // no data on production_vertex
|
---|
131 | {
|
---|
132 | mo1 =0;
|
---|
133 | mo2 =0;
|
---|
134 | }
|
---|
135 | if (index_to_particle[j]->end_vertex())
|
---|
136 | {
|
---|
137 | //find # of 1. daughter
|
---|
138 | int first_daughter = find_in_map( particle_to_index,*(index_to_particle[j]->end_vertex()->particles_begin(HepMC::children)));
|
---|
139 | //cout <<"first_daughter "<< first_daughter << "num_daughters " << num_daughters << endl;
|
---|
140 | HepMC::GenVertex::particle_iterator ic;
|
---|
141 | int last_daughter=0;
|
---|
142 | //find # of last daughter
|
---|
143 | for (ic = index_to_particle[j]->end_vertex()->particles_begin(HepMC::children);ic != index_to_particle[j]->end_vertex()->particles_end(HepMC::children); ++ic)
|
---|
144 | last_daughter= find_in_map( particle_to_index,*ic);
|
---|
145 |
|
---|
146 | if (first_daughter== 0) last_daughter = 0;
|
---|
147 | da1=first_daughter;
|
---|
148 | da2=last_daughter;
|
---|
149 | }
|
---|
150 | else
|
---|
151 | {
|
---|
152 | da1=0;
|
---|
153 | da2=0;
|
---|
154 | }
|
---|
155 | }
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 |
|
---|
160 | //---------------------------------------------------------------------------
|
---|
161 |
|
---|
162 | void HepMCConverter::AnalyseEvent(ExRootTreeBranch *branch,HepMC::GenEvent& evt,const Long64_t eventNumber)
|
---|
163 | {
|
---|
164 | TRootLHEFEvent *element;
|
---|
165 |
|
---|
166 | element = static_cast<TRootLHEFEvent*>(branch->NewEntry());
|
---|
167 | element->Number = eventNumber;
|
---|
168 | element->Nparticles = evt.particles_size();
|
---|
169 | element->ProcessID = evt.signal_process_id();
|
---|
170 | // element->Weight = hepeup.XWGTUP;
|
---|
171 | element->ScalePDF = evt.event_scale();
|
---|
172 | element->CouplingQED = evt.alphaQED();
|
---|
173 | element->CouplingQCD = evt.alphaQCD();
|
---|
174 |
|
---|
175 | }
|
---|
176 |
|
---|
177 | //---------------------------------------------------------------------------
|
---|
178 |
|
---|
179 | void HepMCConverter::AnalyseParticles(ExRootTreeBranch *branch, const HepMC::GenEvent& evt)
|
---|
180 | {
|
---|
181 | TRootC::GenParticle *element;
|
---|
182 |
|
---|
183 | TLorentzVector momentum;
|
---|
184 | Double_t signPz;
|
---|
185 |
|
---|
186 | ReadStats();
|
---|
187 | for(int n=1; n<=evt.particles_size(); n++)
|
---|
188 | {
|
---|
189 | getStatsFromTuple( mo1,mo2,da1,da2,status,pid,n);
|
---|
190 |
|
---|
191 | element = static_cast<TRootC::GenParticle*>(branch->NewEntry());
|
---|
192 |
|
---|
193 | element->PID = pid;
|
---|
194 | element->Status = status;
|
---|
195 | element->M1 = mo1;
|
---|
196 | element->M2 = mo2;
|
---|
197 | element->D1 = da1;
|
---|
198 | element->D2 = da2;
|
---|
199 |
|
---|
200 | element->E = index_to_particle[n]->momentum().e();
|
---|
201 | element->Px = index_to_particle[n]->momentum().px();
|
---|
202 | element->Py = index_to_particle[n]->momentum().py();
|
---|
203 | element->Pz = index_to_particle[n]->momentum().pz();
|
---|
204 |
|
---|
205 |
|
---|
206 | //cout << "element->PID = " << pid << "\t";
|
---|
207 | //PdgParticle pdg_part(PdgID[pid]);
|
---|
208 | //element->M = index_to_particle[n]->momentum().m(); // this is the particle virtuality, not its rest mass
|
---|
209 | //element->M = pdg_part.mass();
|
---|
210 | //element->Charge = pdg_part.charge();
|
---|
211 | //cout << "element->M = " << element->M << " \t element->Charge = " << element->Charge << endl;
|
---|
212 |
|
---|
213 | element->PT = sqrt(pow(element->Px,2)+pow(element->Py,2));
|
---|
214 |
|
---|
215 | momentum.SetPxPyPzE(element->Px, element->Py, element->Pz, element->E);
|
---|
216 | signPz = (element->Pz >= 0.0) ? 1.0 : -1.0;
|
---|
217 | //element->Eta = element->PT == 0.0 ? signPz*999.9 : momentum.Eta(); to avoid a warning from ROOT, replace the "==0" by "< 1e-6"
|
---|
218 | element->Eta = element->PT < 1e-6 ? signPz*999.9 : momentum.Eta();
|
---|
219 | element->Phi = index_to_particle[n]->momentum().phi();
|
---|
220 |
|
---|
221 | //In particle at vertex
|
---|
222 | HepMC::GenVertex* vrtI = (index_to_particle[n])->production_vertex();
|
---|
223 | HepMC::GenVertex::particles_in_const_iterator partI;
|
---|
224 |
|
---|
225 | if(vrtI)
|
---|
226 | {
|
---|
227 | element->T = vrtI->position().t();
|
---|
228 | element->X = vrtI->position().x();
|
---|
229 | element->Y = vrtI->position().y();
|
---|
230 | element->Z = vrtI->position().z();
|
---|
231 | }
|
---|
232 | else
|
---|
233 | {
|
---|
234 | element->T = 0.;
|
---|
235 | element->X = 0.;
|
---|
236 | element->Y = 0.;
|
---|
237 | element->Z = 0.;
|
---|
238 | }
|
---|
239 | }
|
---|
240 | }
|
---|
241 |
|
---|
242 | //
|
---|
243 |
|
---|
244 | //------------------------------------------------------------------------------
|
---|
245 |
|
---|
246 | HepMCConverter::~HepMCConverter()
|
---|
247 | {
|
---|
248 | delete evt;
|
---|
249 |
|
---|
250 | /*cout << "delete index to particle" << endl;
|
---|
251 | std::vector<HepMC::GenParticle*>::iterator i;
|
---|
252 | / for (i=index_to_particle.begin();i != index_to_particle.end(); i++) delete (*i);
|
---|
253 | cout << "done" << endl;
|
---|
254 |
|
---|
255 | std::map<HepMC::GenParticle*,int>::iterator j;
|
---|
256 | for (j=particle_to_index.begin(); j != particle_to_index.end(); j++) delete j->first;
|
---|
257 | */
|
---|
258 |
|
---|
259 | }
|
---|
260 |
|
---|
261 | //------------------------------------------------------------------------------
|
---|
262 |
|
---|
263 | HepMCConverter::HepMCConverter(const string& inputFileList, const string& outputFileName, const PdgTable& pdg, const int& Nevents) : DataConverter(pdg,Nevents)
|
---|
264 | {
|
---|
265 |
|
---|
266 | ExRootTreeWriter *treeWriter = new ExRootTreeWriter(outputFileName, "GEN");
|
---|
267 | // information about generated event
|
---|
268 | ExRootTreeBranch *branchGenEvent = treeWriter->NewBranch("Event", TRootLHEFEvent::Class());
|
---|
269 | // generated particles from HEPEVT
|
---|
270 | ExRootTreeBranch *branchGenParticle = treeWriter->NewBranch("Particle", TRootC::GenParticle::Class());
|
---|
271 |
|
---|
272 | // Open a stream connected to an event file:
|
---|
273 | ifstream infile(inputFileList.c_str());
|
---|
274 | string filename;
|
---|
275 | if(!infile.is_open()) {
|
---|
276 | cerr << left << setw(30) <<"** ERROR: Can't open "<<""
|
---|
277 | << left << setw(20) << inputFileList <<""
|
---|
278 | << right << setw(19) <<"for input **"<<""<<endl;
|
---|
279 | exit(1);
|
---|
280 | }
|
---|
281 |
|
---|
282 | Long64_t entry = 0;
|
---|
283 | while(1)
|
---|
284 | {
|
---|
285 | infile >> filename;
|
---|
286 | if(!infile.good()) break;
|
---|
287 | ifstream checking_the_file(filename.c_str());
|
---|
288 | if(!checking_the_file.good())
|
---|
289 | {
|
---|
290 | cerr << left << setw(30) <<"** ERROR: Can't find file "<<""
|
---|
291 | << left << setw(20) << filename <<""
|
---|
292 | << right << setw(19) <<"for input **"<<""<<endl;
|
---|
293 | continue;
|
---|
294 | }
|
---|
295 | else checking_the_file.close();
|
---|
296 |
|
---|
297 | //Open the file
|
---|
298 | HepMC::IO_GenEvent ascii_in(filename,std::ios::in);
|
---|
299 | // get the first event
|
---|
300 |
|
---|
301 | evt = ascii_in.read_next_event();
|
---|
302 |
|
---|
303 | while ( evt )
|
---|
304 | {
|
---|
305 | if(Nevt>0 && entry>=Nevt) break;
|
---|
306 |
|
---|
307 | treeWriter->Clear();
|
---|
308 | AnalyseEvent(branchGenEvent, *evt,entry+1);
|
---|
309 | AnalyseParticles(branchGenParticle, *evt);
|
---|
310 | delete evt;
|
---|
311 | // read the next event
|
---|
312 | ascii_in >> evt;
|
---|
313 | treeWriter->Fill();
|
---|
314 | ++entry;
|
---|
315 | }
|
---|
316 | }
|
---|
317 |
|
---|
318 | treeWriter->Write();
|
---|
319 | delete treeWriter;
|
---|
320 |
|
---|
321 | }
|
---|
322 |
|
---|
323 |
|
---|
324 |
|
---|
325 |
|
---|