@@ -202,13 +202,40 @@ Bool_t
202202void GeneratorPythia8::updateHeader (o2::dataformats::MCEventHeader* eventHeader)
203203{
204204 /* * update header **/
205-
206- eventHeader->putInfo <std::string>(" generator" , " pythia8" );
207- eventHeader->putInfo <int >(" version" , PYTHIA_VERSION_INTEGER);
208- eventHeader->putInfo <std::string>(" processName" , mPythia .info .name ());
209- eventHeader->putInfo <int >(" processCode" , mPythia .info .code ());
210- eventHeader->putInfo <float >(" weight" , mPythia .info .weight ());
211-
205+ using Key=o2::dataformats::MCInfoKeys;
206+
207+ eventHeader->putInfo <std::string>(Key::generator, " pythia8" );
208+ eventHeader->putInfo <int >(Key::generatorVersion, PYTHIA_VERSION_INTEGER);
209+ eventHeader->putInfo <std::string>(Key::processName, mPythia .info .name ());
210+ eventHeader->putInfo <int >(Key::processCode, mPythia .info .code ());
211+ eventHeader->putInfo <float >(Key::weight, mPythia .info .weight ());
212+
213+ auto & info = mPythia .info ;
214+
215+ // Set PDF information
216+ eventHeader->putInfo <int > (Key::pdfParton1Id, info.id1pdf ());
217+ eventHeader->putInfo <int > (Key::pdfParton2Id, info.id2pdf ());
218+ eventHeader->putInfo <float >(Key::pdfX1, info.x1pdf ());
219+ eventHeader->putInfo <float >(Key::pdfX2, info.x2pdf ());
220+ eventHeader->putInfo <float >(Key::pdfScale, info.QFac ());
221+ eventHeader->putInfo <float >(Key::pdfXF1, info.pdf1 ());
222+ eventHeader->putInfo <float >(Key::pdfXF2, info.pdf2 ());
223+
224+ // Set cross section
225+ eventHeader->putInfo <float >(Key::xSection, info.sigmaGen ()*1e9 );
226+ eventHeader->putInfo <float >(Key::xSectionError,info.sigmaErr ()*1e9 );
227+
228+ // Set weights (overrides cross-section for each weight)
229+ size_t iw = 0 ;
230+ auto xsecErr = info.weightContainerPtr ->getTotalXsecErr ();
231+ for (auto w : info.weightContainerPtr ->getTotalXsec ()) {
232+ std::string post = (iw == 0 ? " " : " _" +std::to_string (iw));
233+ eventHeader->putInfo <float >(Key::weight+post , info.weightValueByIndex (iw));
234+ eventHeader->putInfo <float >(Key::xSection+post ,w*1e9 );
235+ eventHeader->putInfo <float >(Key::xSectionError+post ,xsecErr[iw]*1e9 );
236+ iw++;
237+ }
238+
212239#if PYTHIA_VERSION_INTEGER < 8300
213240 auto hiinfo = mPythia .info .hiinfo ;
214241#else
@@ -218,7 +245,7 @@ void GeneratorPythia8::updateHeader(o2::dataformats::MCEventHeader* eventHeader)
218245 if (hiinfo) {
219246 /* * set impact parameter **/
220247 eventHeader->SetB (hiinfo->b ());
221- eventHeader->putInfo <double >(" Bimpact " , hiinfo->b ());
248+ eventHeader->putInfo <double >(Key::impactParameter , hiinfo->b ());
222249 auto bImp = hiinfo->b ();
223250 /* * set Ncoll, Npart and Nremn **/
224251 int nColl, nPart;
@@ -230,7 +257,8 @@ void GeneratorPythia8::updateHeader(o2::dataformats::MCEventHeader* eventHeader)
230257 getNpart (nPartProtonProj, nPartNeutronProj, nPartProtonTarg, nPartNeutronTarg);
231258 getNremn (nRemnProtonProj, nRemnNeutronProj, nRemnProtonTarg, nRemnNeutronTarg);
232259 getNfreeSpec (nFreeNeutronProj, nFreeProtonProj, nFreeNeutronTarg, nFreeProtonTarg);
233- eventHeader->putInfo <int >(" Ncoll" , nColl);
260+ eventHeader->putInfo <int >(Key::nColl, nColl);
261+ // These are all non-HepMC3 fields - of limited use
234262 eventHeader->putInfo <int >(" Npart" , nPart);
235263 eventHeader->putInfo <int >(" Npart_proj_p" , nPartProtonProj);
236264 eventHeader->putInfo <int >(" Npart_proj_n" , nPartNeutronProj);
@@ -244,6 +272,19 @@ void GeneratorPythia8::updateHeader(o2::dataformats::MCEventHeader* eventHeader)
244272 eventHeader->putInfo <int >(" Nfree_proj_p" , nFreeProtonProj);
245273 eventHeader->putInfo <int >(" Nfree_targ_n" , nFreeNeutronTarg);
246274 eventHeader->putInfo <int >(" Nfree_targ_p" , nFreeProtonTarg);
275+
276+ // --- HepMC3 conforming information ---
277+ // This is how the Pythia authors define Ncoll
278+ // eventHeader->putInfo<int>(Key::nColl,
279+ // hiinfo->nAbsProj() + hiinfo->nDiffProj() +
280+ // hiinfo->nAbsTarg() + hiinfo->nDiffTarg() -
281+ // hiiinfo->nCollND() - hiinfo->nCollDD());
282+ eventHeader->putInfo <int >(Key::nPartProjectile,
283+ hiinfo->nAbsProj ()+hiinfo->nDiffProj ());
284+ eventHeader->putInfo <int >(Key::nPartTarget,
285+ hiinfo->nAbsTarg ()+hiinfo->nDiffTarg ());
286+ eventHeader->putInfo <int >(Key::nCollHard, hiinfo->nCollNDTot ());
287+
247288 }
248289}
249290
@@ -302,6 +343,10 @@ void GeneratorPythia8::getNcoll(const Pythia8::Info& info, int& nColl)
302343 auto hiinfo = info.hiInfo ;
303344#endif
304345
346+ // This is how the Pythia authors define Ncoll
347+ nColl = (hiinfo->nAbsProj ()+hiinfo->nDiffProj ()+
348+ hiinfo->nAbsTarg ()+hiinfo->nDiffTarg ()-
349+ hiinfo->nCollND () -hiinfo->nCollDD ());
305350 nColl = 0 ;
306351
307352 if (!hiinfo) {
@@ -330,6 +375,16 @@ void GeneratorPythia8::getNpart(const Pythia8::Info& info, int& nPart)
330375
331376 /* * compute number of participants as the sum of all participants nucleons **/
332377
378+ // This is how the Pythia authors calculate Npart
379+ #if PYTHIA_VERSION_INTEGER < 8300
380+ auto hiinfo = info.hiinfo ;
381+ #else
382+ auto hiinfo = info.hiInfo ;
383+ #endif
384+ if (hiinfo)
385+ nPart = (hiinfo->nAbsProj () + hiinfo->nDiffProj () +
386+ hiinfo->nAbsTarg () + hiinfo->nDiffTarg ());
387+
333388 int nProtonProj, nNeutronProj, nProtonTarg, nNeutronTarg;
334389 getNpart (info, nProtonProj, nNeutronProj, nProtonTarg, nNeutronTarg);
335390 nPart = nProtonProj + nNeutronProj + nProtonTarg + nNeutronTarg;
0 commit comments