Fork me on GitHub

source: git/classes/DelphesHepMC3Reader.cc@ 4006893

Last change on this file since 4006893 was 4006893, checked in by Pavel Demin <pavel.demin@…>, 3 years ago

fix order of decay products in DelphesHepMC3Reader

  • Property mode set to 100644
File size: 13.5 KB
Line 
1/*
2 * Delphes: a framework for fast simulation of a generic collider experiment
3 * Copyright (C) 2012-2021 Universite catholique de Louvain (UCL), Belgium
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/** \class DelphesHepMC3Reader
20 *
21 * Reads HepMC file
22 *
23 * \author P. Demin - UCL, Louvain-la-Neuve
24 *
25 */
26
27#include "classes/DelphesHepMC3Reader.h"
28
29#include <iostream>
30#include <sstream>
31#include <stdexcept>
32
33#include <map>
34#include <vector>
35
36#include <stdio.h>
37
38#include "TDatabasePDG.h"
39#include "TLorentzVector.h"
40#include "TObjArray.h"
41#include "TParticlePDG.h"
42#include "TStopwatch.h"
43
44#include "classes/DelphesClasses.h"
45#include "classes/DelphesFactory.h"
46#include "classes/DelphesStream.h"
47
48#include "ExRootAnalysis/ExRootTreeBranch.h"
49
50using namespace std;
51
52static const int kBufferSize = 16384;
53
54//---------------------------------------------------------------------------
55
56DelphesHepMC3Reader::DelphesHepMC3Reader() :
57 fInputFile(0), fBuffer(0), fPDG(0),
58 fVertexCounter(-2), fParticleCounter(-1)
59{
60 fBuffer = new char[kBufferSize];
61
62 fPDG = TDatabasePDG::Instance();
63}
64
65//---------------------------------------------------------------------------
66
67DelphesHepMC3Reader::~DelphesHepMC3Reader()
68{
69 if(fBuffer) delete[] fBuffer;
70}
71
72//---------------------------------------------------------------------------
73
74void DelphesHepMC3Reader::SetInputFile(FILE *inputFile)
75{
76 fInputFile = inputFile;
77}
78
79//---------------------------------------------------------------------------
80
81void DelphesHepMC3Reader::Clear()
82{
83 fWeights.clear();
84 fMomentumCoefficient = 1.0;
85 fPositionCoefficient = 1.0;
86 fVertexCounter = -2;
87 fParticleCounter = -1;
88 fVertices.clear();
89 fParticles.clear();
90 fInVertexMap.clear();
91 fOutVertexMap.clear();
92 fMotherMap.clear();
93 fDaughterMap.clear();
94}
95
96//---------------------------------------------------------------------------
97
98bool DelphesHepMC3Reader::EventReady()
99{
100 return (fVertexCounter == -1) && (fParticleCounter == 0);
101}
102
103//---------------------------------------------------------------------------
104
105bool DelphesHepMC3Reader::ReadBlock(DelphesFactory *factory,
106 TObjArray *allParticleOutputArray,
107 TObjArray *stableParticleOutputArray,
108 TObjArray *partonOutputArray)
109{
110 map<int, pair<int, int> >::iterator itDaughterMap;
111 char key, momentumUnit[4], positionUnit[3];
112 int rc, code;
113 double weight;
114
115 if(!fgets(fBuffer, kBufferSize, fInputFile)) return kFALSE;
116
117 DelphesStream bufferStream(fBuffer + 1);
118
119 key = fBuffer[0];
120
121 if(key == 'E')
122 {
123 Clear();
124
125 rc = bufferStream.ReadInt(fEventNumber)
126 && bufferStream.ReadInt(fVertexCounter)
127 && bufferStream.ReadInt(fParticleCounter);
128
129 if(!rc)
130 {
131 cerr << "** ERROR: "
132 << "invalid event format" << endl;
133 return kFALSE;
134 }
135 }
136 else if(key == 'U')
137 {
138 rc = sscanf(fBuffer + 1, "%3s %2s", momentumUnit, positionUnit);
139
140 if(rc != 2)
141 {
142 cerr << "** ERROR: "
143 << "invalid units format" << endl;
144 return kFALSE;
145 }
146
147 if(strncmp(momentumUnit, "GEV", 3) == 0)
148 {
149 fMomentumCoefficient = 1.0;
150 }
151 else if(strncmp(momentumUnit, "MEV", 3) == 0)
152 {
153 fMomentumCoefficient = 0.001;
154 }
155
156 if(strncmp(positionUnit, "MM", 3) == 0)
157 {
158 fPositionCoefficient = 1.0;
159 }
160 else if(strncmp(positionUnit, "CM", 3) == 0)
161 {
162 fPositionCoefficient = 10.0;
163 }
164 }
165 else if(key == 'W')
166 {
167 while(bufferStream.ReadDbl(weight))
168 {
169 fWeights.push_back(weight);
170 }
171 }
172 else if(key == 'A' && bufferStream.FindStr("mpi"))
173 {
174 rc = bufferStream.ReadInt(fMPI);
175
176 if(!rc)
177 {
178 cerr << "** ERROR: "
179 << "invalid MPI format" << endl;
180 return kFALSE;
181 }
182 }
183 else if(key == 'A' && bufferStream.FindStr("signal_process_id"))
184 {
185 rc = bufferStream.ReadInt(fProcessID);
186
187 if(!rc)
188 {
189 cerr << "** ERROR: "
190 << "invalid process ID format" << endl;
191 return kFALSE;
192 }
193 }
194 else if(key == 'A' && bufferStream.FindStr("event_scale"))
195 {
196 rc = bufferStream.ReadDbl(fScale);
197
198 if(!rc)
199 {
200 cerr << "** ERROR: "
201 << "invalid event scale format" << endl;
202 return kFALSE;
203 }
204 }
205 else if(key == 'A' && bufferStream.FindStr("alphaQCD"))
206 {
207 rc = bufferStream.ReadDbl(fAlphaQCD);
208
209 if(!rc)
210 {
211 cerr << "** ERROR: "
212 << "invalid alphaQCD format" << endl;
213 return kFALSE;
214 }
215 }
216 else if(key == 'A' && bufferStream.FindStr("alphaQED"))
217 {
218 rc = bufferStream.ReadDbl(fAlphaQED);
219
220 if(!rc)
221 {
222 cerr << "** ERROR: "
223 << "invalid alphaQED format" << endl;
224 return kFALSE;
225 }
226 }
227 else if(key == 'A' && bufferStream.FindStr("GenCrossSection"))
228 {
229 rc = bufferStream.ReadDbl(fCrossSection)
230 && bufferStream.ReadDbl(fCrossSectionError);
231
232 if(!rc)
233 {
234 cerr << "** ERROR: "
235 << "invalid cross section format" << endl;
236 return kFALSE;
237 }
238 }
239 else if(key == 'A' && bufferStream.FindStr("GenPdfInfo"))
240 {
241 rc = bufferStream.ReadInt(fID1)
242 && bufferStream.ReadInt(fID2)
243 && bufferStream.ReadDbl(fX1)
244 && bufferStream.ReadDbl(fX2)
245 && bufferStream.ReadDbl(fScalePDF)
246 && bufferStream.ReadDbl(fPDF1)
247 && bufferStream.ReadDbl(fPDF2);
248
249 if(!rc)
250 {
251 cerr << "** ERROR: "
252 << "invalid PDF format" << endl;
253 return kFALSE;
254 }
255 }
256 else if(key == 'V')
257 {
258 fParticles.clear();
259
260 fX = 0.0;
261 fY = 0.0;
262 fZ = 0.0;
263 fT = 0.0;
264
265 rc = bufferStream.ReadInt(fVertexCode)
266 && bufferStream.ReadInt(fVertexStatus);
267
268 if(!rc)
269 {
270 cerr << "** ERROR: "
271 << "invalid vertex format" << endl;
272 return kFALSE;
273 }
274
275 rc = bufferStream.FindChr('[');
276
277 if(!rc)
278 {
279 cerr << "** ERROR: "
280 << "invalid vertex format" << endl;
281 return kFALSE;
282 }
283
284 while(bufferStream.ReadInt(code))
285 {
286 fParticles.push_back(code);
287 bufferStream.FindChr(',');
288 }
289
290 if(bufferStream.FindChr('@'))
291 {
292 rc = bufferStream.ReadDbl(fX)
293 && bufferStream.ReadDbl(fY)
294 && bufferStream.ReadDbl(fZ)
295 && bufferStream.ReadDbl(fT);
296
297 if(!rc)
298 {
299 cerr << "** ERROR: "
300 << "invalid vertex format" << endl;
301 return kFALSE;
302 }
303 }
304
305 AnalyzeVertex(factory, fVertexCode);
306 }
307 else if(key == 'P' && fParticleCounter > 0)
308 {
309 --fParticleCounter;
310
311 rc = bufferStream.ReadInt(fParticleCode)
312 && bufferStream.ReadInt(fOutVertexCode)
313 && bufferStream.ReadInt(fPID)
314 && bufferStream.ReadDbl(fPx)
315 && bufferStream.ReadDbl(fPy)
316 && bufferStream.ReadDbl(fPz)
317 && bufferStream.ReadDbl(fE)
318 && bufferStream.ReadDbl(fMass)
319 && bufferStream.ReadInt(fParticleStatus);
320
321 if(!rc)
322 {
323 cerr << "** ERROR: "
324 << "invalid particle format" << endl;
325 return kFALSE;
326 }
327
328 AnalyzeParticle(factory, allParticleOutputArray,
329 stableParticleOutputArray, partonOutputArray);
330 }
331
332 if(EventReady())
333 {
334 FinalizeParticles(allParticleOutputArray);
335 }
336
337 return kTRUE;
338}
339
340//---------------------------------------------------------------------------
341
342void DelphesHepMC3Reader::AnalyzeEvent(ExRootTreeBranch *branch, long long eventNumber,
343 TStopwatch *readStopWatch, TStopwatch *procStopWatch)
344{
345 HepMCEvent *element;
346
347 element = static_cast<HepMCEvent *>(branch->NewEntry());
348 element->Number = fEventNumber;
349
350 element->ProcessID = fProcessID;
351 element->MPI = fMPI;
352 element->Weight = fWeights.size() > 0 ? fWeights[0] : 1.0;
353 element->CrossSection = fCrossSection;
354 element->CrossSectionError = fCrossSectionError;
355 element->Scale = fScale;
356 element->AlphaQED = fAlphaQED;
357 element->AlphaQCD = fAlphaQCD;
358
359 element->ID1 = fID1;
360 element->ID2 = fID2;
361 element->X1 = fX1;
362 element->X2 = fX2;
363 element->ScalePDF = fScalePDF;
364 element->PDF1 = fPDF1;
365 element->PDF2 = fPDF2;
366
367 element->ReadTime = readStopWatch->RealTime();
368 element->ProcTime = procStopWatch->RealTime();
369}
370
371//---------------------------------------------------------------------------
372
373void DelphesHepMC3Reader::AnalyzeWeight(ExRootTreeBranch *branch)
374{
375 Weight *element;
376 vector<double>::const_iterator itWeight;
377
378 for(itWeight = fWeights.begin(); itWeight != fWeights.end(); ++itWeight)
379 {
380 element = static_cast<Weight *>(branch->NewEntry());
381
382 element->Weight = *itWeight;
383 }
384}
385
386//---------------------------------------------------------------------------
387
388void DelphesHepMC3Reader::AnalyzeVertex(DelphesFactory *factory, int code, Candidate *candidate)
389{
390 int index;
391 TLorentzVector *position;
392 TObjArray *array;
393 vector<int>::iterator itParticle;
394 map<int, int>::iterator itVertexMap;
395
396 itVertexMap = fOutVertexMap.find(code);
397 if(itVertexMap == fOutVertexMap.end())
398 {
399 --fVertexCounter;
400
401 index = fVertices.size();
402 fOutVertexMap[code] = index;
403 if(candidate && code > 0) fInVertexMap[code] = index;
404
405 position = factory->New<TLorentzVector>();
406 array = factory->NewArray();
407 position->SetXYZT(0.0, 0.0, 0.0, 0.0);
408 array->Clear();
409 fVertices.push_back(make_pair(position, array));
410 }
411 else
412 {
413 index = itVertexMap->second;
414 position = fVertices[index].first;
415 array = fVertices[index].second;
416 }
417
418 if(candidate)
419 {
420 array->Add(candidate);
421 }
422 else
423 {
424 position->SetXYZT(fX, fY, fZ, fT);
425 for(itParticle = fParticles.begin(); itParticle != fParticles.end(); ++itParticle)
426 {
427 fInVertexMap[*itParticle] = index;
428 }
429 }
430}
431
432//---------------------------------------------------------------------------
433
434void DelphesHepMC3Reader::AnalyzeParticle(DelphesFactory *factory,
435 TObjArray *allParticleOutputArray,
436 TObjArray *stableParticleOutputArray,
437 TObjArray *partonOutputArray)
438{
439 Candidate *candidate;
440 TParticlePDG *pdgParticle;
441 int pdgCode;
442
443 candidate = factory->NewCandidate();
444
445 candidate->PID = fPID;
446 pdgCode = TMath::Abs(candidate->PID);
447
448 candidate->Status = fParticleStatus;
449
450 pdgParticle = fPDG->GetParticle(fPID);
451 candidate->Charge = pdgParticle ? int(pdgParticle->Charge() / 3.0) : -999;
452 candidate->Mass = fMass;
453
454 candidate->Momentum.SetPxPyPzE(fPx, fPy, fPz, fE);
455 if(fMomentumCoefficient != 1.0)
456 {
457 candidate->Momentum *= fMomentumCoefficient;
458 }
459
460 candidate->D1 = fParticleCode;
461
462 AnalyzeVertex(factory, fOutVertexCode, candidate);
463
464 if(!pdgParticle) return;
465
466 if(fParticleStatus == 1)
467 {
468 stableParticleOutputArray->Add(candidate);
469 }
470 else if(pdgCode <= 5 || pdgCode == 21 || pdgCode == 15)
471 {
472 partonOutputArray->Add(candidate);
473 }
474}
475
476//---------------------------------------------------------------------------
477
478void DelphesHepMC3Reader::FinalizeParticles(TObjArray *allParticleOutputArray)
479{
480 TLorentzVector *position;
481 TObjArray *array;
482 Candidate *candidate;
483 map<int, int >::iterator itVertexMap;
484 map<int, pair<int, int> >::iterator itMotherMap;
485 map<int, pair<int, int> >::iterator itDaughterMap;
486 int i, j, code, counter;
487
488 counter = 0;
489 for(i = 0; i < fVertices.size(); ++i)
490 {
491 position = fVertices[i].first;
492 array = fVertices[i].second;
493
494 for(j = 0; j < array->GetEntriesFast(); ++j)
495 {
496 candidate = static_cast<Candidate *>(array->At(j));
497
498 candidate->Position = *position;
499 if(fPositionCoefficient != 1.0)
500 {
501 candidate->Position *= fPositionCoefficient;
502 }
503
504 candidate->M1 = i;
505
506 itDaughterMap = fDaughterMap.find(i);
507 if(itDaughterMap == fDaughterMap.end())
508 {
509 fDaughterMap[i] = make_pair(counter, counter);
510 }
511 else
512 {
513 itDaughterMap->second.second = counter;
514 }
515
516 code = candidate->D1;
517
518 itVertexMap = fInVertexMap.find(code);
519 if(itVertexMap == fInVertexMap.end())
520 {
521 candidate->D1 = -1;
522 }
523 else
524 {
525 code = itVertexMap->second;
526
527 candidate->D1 = code;
528
529 itMotherMap = fMotherMap.find(code);
530 if(itMotherMap == fMotherMap.end())
531 {
532 fMotherMap[code] = make_pair(counter, -1);
533 }
534 else
535 {
536 itMotherMap->second.second = counter;
537 }
538 }
539
540 allParticleOutputArray->Add(candidate);
541
542 ++counter;
543 }
544 }
545
546 for(i = 0; i < allParticleOutputArray->GetEntriesFast(); ++i)
547 {
548 candidate = static_cast<Candidate *>(allParticleOutputArray->At(i));
549
550 itMotherMap = fMotherMap.find(candidate->M1);
551 if(itMotherMap == fMotherMap.end())
552 {
553 candidate->M1 = -1;
554 candidate->M2 = -1;
555 }
556 else
557 {
558 candidate->M1 = itMotherMap->second.first;
559 candidate->M2 = itMotherMap->second.second;
560 }
561
562 if(candidate->D1 < 0)
563 {
564 candidate->D1 = -1;
565 candidate->D2 = -1;
566 }
567 else
568 {
569 itDaughterMap = fDaughterMap.find(candidate->D1);
570 if(itDaughterMap == fDaughterMap.end())
571 {
572 candidate->D1 = -1;
573 candidate->D2 = -1;
574 }
575 else
576 {
577 candidate->D1 = itDaughterMap->second.first;
578 candidate->D2 = itDaughterMap->second.second;
579 }
580 }
581 }
582}
583
584//---------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.