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