17 #include <TDatabasePDG.h>
22 #include "HepMC3/GenEvent.h"
23 #include "HepMC3/GenVertex.h"
24 #include "HepMC3/GenParticle.h"
25 #include "HepMC3/GenCrossSection.h"
26 #include "HepMC3/Attribute.h"
27 #include "HepMC3/Version.h"
28 #include "HepMC3/WriterAscii.h"
29 #include "HepMC3/WriterAsciiHepMC2.h"
30 #include "HepMC3/WriterRoot.h"
31 #include "HepMC3/WriterRootTree.h"
39 using HepMC3::FourVector;
40 using HepMC3::GenRunInfo;
41 using HepMC3::GenEvent;
42 using HepMC3::GenParticle;
43 using HepMC3::GenParticlePtr;
44 using HepMC3::GenVertex;
45 using HepMC3::GenVertexPtr;
46 using HepMC3::GenCrossSection;
47 using HepMC3::GenCrossSectionPtr;
57 const std::string& outputDirName,
62 if ( !TString(inputFileName).EndsWith(
".root", TString::kIgnoreCase) ){
63 cerr <<
"Warning: " << inputFileName <<
" does not end with .root" << endl;
68 TFile inFile(inputFileName.c_str(),
"READ");
69 if (!inFile.IsOpen()) {
70 std::cerr <<
"Unable to open " << inputFileName << std::endl;
74 inFile.GetObject(
"EICTree", mcTree);
76 std::cerr <<
"Unable to find EICTree in " << inputFileName << std::endl;
80 mcTree->SetBranchAddress(
"event",&inEvent);
83 TClass* branchClass = TClass::GetClass(mcTree->GetBranch(
"event")->GetClassName());
84 TString generatorname = branchClass->GetName();
85 if (branchClass->InheritsFrom(
"erhic::EventDis")) {
86 generatorname.ReplaceAll(
"erhic::Event",
"");
88 cerr << branchClass->GetName() <<
" is not supported." << endl;
93 bool beaglemode=
false;
94 if (branchClass->InheritsFrom(
"erhic::EventBeagle")) {
95 cout <<
"Warning: BeAGLE support is rudimentary. Can't fix mother-daughter structure." << endl;
101 bool legacymilou=
false;
102 bool milouwarn=
false;
103 if (branchClass->InheritsFrom(
"erhic::EventMilou")) {
108 std::shared_ptr<GenRunInfo>
run = std::make_shared<GenRunInfo>();
109 struct GenRunInfo::ToolInfo generator={
110 std::string(generatorname),
111 std::string(
"unknown version"),
112 std::string(
"Used generator")
114 run->tools().push_back(generator);
121 std::vector<std::string> wnames;
122 if (!wnames.size()) wnames.push_back(
"default");
123 run->set_weight_names(wnames);
130 double crossSection = 1.0;
131 double crossSectionError = 0.0;
135 std::vector <string> RunAttributes = {
"crossSection",
"crossSectionError",
"nEvents",
"nTrials" };
136 for (
auto att : RunAttributes ){
137 TObjString* ObjString(
nullptr);
138 inFile.GetObject(att.c_str(), ObjString);
140 double value = std::atof(ObjString->String());
141 if ( att ==
"crossSection" ) {
144 crossSection =
value;
146 if ( att ==
"crossSectionError" ){
149 crossSectionError =
value;
151 cout <<
" Adding to the header: " << att <<
" " << value << endl;
152 run->add_attribute( att, std::make_shared<HepMC3::DoubleAttribute>( value )) ;
159 TString outName = gSystem->BaseName(inputFileName.c_str());
161 outName.Replace(outName.Last(
'.'), outName.Length(),
"");
162 outName.Append(
".hepmc");
164 TString outDir(outputDirName);
165 if (!outDir.EndsWith(
"/")) outDir.Append(
'/');
166 outName.Prepend(outDir);
170 std::shared_ptr<HepMC3::Writer>
file;
173 file = std::make_shared<HepMC3::WriterAsciiHepMC2>(outName.Data(),
run);
176 file = std::make_shared<HepMC3::WriterAscii>(outName.Data(),
run);
180 outName.Append(
".root");
181 file = std::make_shared<HepMC3::WriterRootTree>(outName.Data(),
run);
186 outName.Append(
".root");
187 file = std::make_shared<HepMC3::WriterRoot>(outName.Data(),
run);
190 cerr <<
"Unknown HepMC_outtype" << endl;
196 if (mcTree->GetEntries() < maxEvent || maxEvent < 1) {
197 maxEvent = mcTree->GetEntries();
200 "/-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-/"
203 "/ Commencing conversion of " << maxEvent <<
" events."
206 "/-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-/"
209 for (Long64_t i(0); i < maxEvent; i++) {
210 if (i % 10000 == 0 && i != 0) {
211 std::cout <<
"Processing event " << i << std::endl;
217 GenEvent hepmc3evt( HepMC3::Units::GEV, HepMC3::Units::CM );
218 hepmc3evt.set_event_number(i);
219 hepmc3evt.weights().clear();
220 hepmc3evt.weights().push_back(1.0);
223 GenCrossSectionPtr xsec = std::make_shared<GenCrossSection>();
224 xsec->set_cross_section( crossSection, crossSectionError);
225 hepmc3evt.set_cross_section(xsec);
229 auto leaves = mcTree->GetListOfLeaves();
230 for (
int l = 0 ; l < leaves->GetEntries(); ++l ){
231 TLeaf* leaf = (TLeaf*) leaves->At(l);
232 TString lname = leaf->GetName();
233 TString
c = leaf->GetTypeName();
234 if ( lname.BeginsWith(
"particles") )
continue;
238 if ( lname ==
"weight"){
239 hepmc3evt.weights().clear();
240 hepmc3evt.weights().push_back( leaf->GetValue() );
244 if ( lname.Contains(
"char", TString::kIgnoreCase) ) {
249 if ( lname.Contains(
"long", TString::kIgnoreCase) ) {
250 hepmc3evt.add_attribute(lname.Data(),std::make_shared<HepMC3::LongAttribute>( leaf->GetValue() )) ;
253 if ( lname.Contains(
"int", TString::kIgnoreCase)
254 || lname.Contains(
"short", TString::kIgnoreCase) ) {
255 hepmc3evt.add_attribute(lname.Data(),std::make_shared<HepMC3::IntAttribute>( leaf->GetValue() )) ;
258 if ( lname.Contains(
"float", TString::kIgnoreCase)
259 || lname.Contains(
"double", TString::kIgnoreCase) ) {
260 hepmc3evt.add_attribute(lname.Data(),std::make_shared<HepMC3::DoubleAttribute>( leaf->GetValue() )) ;
297 auto myindex = inParticle->
GetIndex();
307 if ( myindex==scatteredindex ){
316 if ( myindex==bosonindex ){
322 auto pdg = TDatabasePDG::Instance()->GetParticle( inParticle->
Id() );
329 }
else if ( !TString(
pdg->ParticleClass()).Contains(
"Lepton")
330 && !TString(
pdg->ParticleClass()).Contains(
"Baryon")
331 && !TString(
pdg->ParticleClass()).Contains(
"Meson")
342 std::cout <<
"Processing event " << i << std::endl;
343 std::cout <<
"Processing track " <<
t <<
" with index " << inParticle->
GetIndex() << std::endl;
344 std::cout <<
"I am a hadron or lepton with status 2, but I do not have children. " << std::endl;
350 std::cout <<
"Processing event " << i << std::endl;
351 std::cout <<
"Processing track " <<
t <<
" with index " << inParticle->
GetIndex() << std::endl;
352 std::cout <<
"Warning: I am a hadron or lepton with status 2, but I have too many parents. " << std::endl;
353 std::cout <<
"Discarding the older one" << std::endl;
360 std::cout <<
"Processing event " << i << std::endl;
361 std::cout <<
"Processing track " <<
t <<
" with index " << inParticle->
GetIndex() << std::endl;
362 std::cout <<
"I am a hadron or lepton with status 2, but I have no parents. " << std::endl;
366 if (
mom->GetStatus() == 1 ){
367 std::cout <<
"Processing event " << i << std::endl;
368 std::cout <<
"Processing track " <<
t <<
" with index " << inParticle->
GetIndex() << std::endl;
369 std::cout <<
"I am a hadron or lepton with status 2, but my mother is final. " << std::endl;
372 if (
mom->GetStatus() != 2 ){
385 if (
mom->GetStatus() == 2 ){
414 cout <<
"Warning: Trying to repair legay Milou's parentage issues." << endl;
462 auto myindex = inParticle->
GetIndex();
472 bool djangohproblem =
false;
474 for ( UShort_t
c =
c1;
c<=cN; ++
c ){
477 cerr <<
"Trying to access a non-existant child" << endl;
478 cerr <<
"Event is " << i <<
" Problem index is " <<
c << endl;
479 cerr <<
"If this is not a djangoh file, please contact the eic-smear developers"<<endl;
480 djangohproblem =
true;
488 if ( p1==0 && pN==0 ){
490 }
else if ( p1==0 ) {
491 if ( pN != myindex ){
504 cout <<
"Found more than one parent in a non-BeAGLE file. Please contact the authors." << endl;
532 if(djangohproblem)
continue;
541 for (
unsigned int p = p1;
p<=pN ; ++
p ){
546 if ( pc1 > myindex ){
550 if ( pcN < myindex ){
560 std::vector<GenParticlePtr> hepevt_particles;
561 hepevt_particles.reserve( inEvent->
GetNTracks() );
568 cout <<
"Status is 1 but we have children?" << endl;
588 FourVector pv = FourVector( inParticle->
GetPx(), inParticle->
GetPy(), inParticle->
GetPz(),inParticle->
GetE() );
589 int statusHepMC = inParticle->
GetStatus();
597 if ( ! beaglemode &&
t>3 ){
599 auto pdg = TDatabasePDG::Instance()->GetParticle( inParticle->
Id() );
601 if ( TString(
pdg->ParticleClass()).Contains(
"Lepton")
602 || TString(
pdg->ParticleClass()).Contains(
"Baryon")
603 || TString(
pdg->ParticleClass()).Contains(
"Meson")
621 if ( statusHepMC != 1 && statusHepMC != 2 && statusHepMC != 4 ){
622 while ( statusHepMC <=10 ) statusHepMC+=10;
623 while ( statusHepMC >200 ) statusHepMC-=10;
630 if( statusHepMC == 4) statusHepMC = 1;
633 hepevt_particles.push_back( std::make_shared<GenParticle>( pv, inParticle->
Id(), statusHepMC ));
634 hepevt_particles.back()->set_generated_mass( inParticle->
GetM() );
646 int index_lepton = lepton->
GetIndex();
647 if ( index_lepton !=1 ) std::cout <<
"Warning: Found BeamLepton at " << index_lepton << endl;
648 auto hep_lepton = hepevt_particles.at( index_lepton-1);
649 hep_lepton->set_status(4);
652 int index_boson = boson->
GetIndex();
659 auto hep_boson = hepevt_particles.at( index_boson-1);
662 GenVertexPtr v_lepton = std::make_shared<GenVertex>();
663 v_lepton->add_particle_in (hep_lepton);
664 v_lepton->add_particle_out (hep_boson);
665 hepmc3evt.add_vertex(v_lepton);
668 int index_hadron = hadron->
GetIndex();
669 if ( index_hadron !=2 ) std::cout <<
"Warning: Found BeamHadron at " << index_hadron << endl;
670 auto hep_hadron = hepevt_particles.at( index_hadron-1);
671 hep_hadron->set_status(4);
672 GenVertexPtr v_hadron = std::make_shared<GenVertex>();
674 v_hadron->add_particle_in (hep_hadron);
675 hepmc3evt.add_vertex(v_hadron);
700 GenVertexPtr v_beagle_final = std::make_shared<GenVertex>();
702 v_hadron->add_particle_in(hep_boson);
703 hepmc3evt.add_vertex( v_beagle_final );
726 if ( index==index_lepton || index==index_boson || index==index_hadron)
continue;
727 auto hep_in = hepevt_particles.at( index-1);
729 auto hep_mom = hep_hadron;
731 auto statusHepMC = inParticle->
GetStatus();
735 if (branchClass->InheritsFrom(
"erhic::EventDjangoh")){
736 if( statusHepMC==1 && momindex==1 &&
737 (
abs(inParticle->
Id())==1 ||
abs(inParticle->
Id())==2 ||
abs(inParticle->
Id())==3 ||
738 abs(inParticle->
Id())==90 || inParticle->
Id()==91 || inParticle->
Id()==92) ){
745 if ( beaglemode && statusHepMC==3 )
continue;
746 if ( beaglemode && statusHepMC==14 )
continue;
747 if ( beaglemode && statusHepMC==18 )
continue;
748 if ( beaglemode && statusHepMC==12 )
continue;
755 if ( momindex == beagle_final_index ){
756 v_beagle_final->add_particle_out(hep_in);
762 if ( beaglemode && statusHepMC!=1 && statusHepMC!=2 ){
763 v_beagle_final->add_particle_in(hep_in);
768 hep_mom = hepevt_particles.at( momindex-1);
772 auto momend = hep_mom->end_vertex();
774 momend = std::make_shared<GenVertex>();
775 momend->add_particle_in(hep_mom);
776 hepmc3evt.add_vertex(momend);
779 momend->add_particle_out(hep_in);
784 momend->set_position( FourVector( vnew.x(), vnew.y(), vnew.z(), 0));
790 file->write_event(hepmc3evt);
809 const std::string& outputDirName,
811 const bool createHepMC2){
812 if ( createHepMC2 ) {
813 cout <<
"Warning, this interface is deprecated, please use:" << endl;
814 cout <<
"TreeToHepMC(\""<< inputFileName<<
"\",\""<< outputDirName
815 <<
"\","<< maxEvent <<
","
816 <<
"erhic::HepMC_outtype::HepMC2)"
820 cout <<
"Warning, this interface is deprecated, please use:" << endl;
821 cout <<
"TreeToHepMC(\""<< inputFileName<<
"\",\""<< outputDirName
822 <<
"\","<< maxEvent <<
","
823 <<
"erhic::HepMC_outtype::HepMC3)"