File indexing completed on 2024-09-28 07:02:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "eicsmear/erhic/EventFactoryHepMC.h"
0011
0012 #include <memory>
0013 #include <stdexcept>
0014 #include <string>
0015
0016 #include <TClass.h>
0017 #include <TProcessID.h>
0018
0019 #include "eicsmear/erhic/BeamParticles.h"
0020 #include "eicsmear/erhic/EventPythia.h"
0021 #include "eicsmear/erhic/EventHepMC.h"
0022 #include "eicsmear/erhic/EventMilou.h"
0023 #include "eicsmear/erhic/EventDjangoh.h"
0024 #include "eicsmear/erhic/EventDpmjet.h"
0025 #include "eicsmear/erhic/EventRapgap.h"
0026 #include "eicsmear/erhic/EventPepsi.h"
0027 #include "eicsmear/erhic/EventGmcTrans.h"
0028 #include "eicsmear/erhic/EventSimple.h"
0029 #include "eicsmear/erhic/EventDEMP.h"
0030 #include "eicsmear/erhic/EventSartre.h"
0031 #include "eicsmear/functions.h" // For getFirstNonBlank()
0032 #include "eicsmear/erhic/Kinematics.h"
0033 #include "eicsmear/erhic/ParticleIdentifier.h"
0034 #include "eicsmear/erhic/ParticleMC.h"
0035
0036 #include <HepMC3/ReaderAsciiHepMC2.h>
0037 #include <HepMC3/ReaderAscii.h>
0038 #include "HepMC3/GenVertex.h"
0039
0040
0041
0042 #include <HepMC3/Version.h>
0043 #if HEPMC3_VERSION_CODE < 3002004
0044 #include <eicsmear/HepMC_3_2_4_ReaderFactory.h>
0045 #else
0046 #include <HepMC3/ReaderFactory.h>
0047 #endif
0048
0049 #include <TVector3.h>
0050 #include <TParticlePDG.h>
0051 #include <TLorentzVector.h>
0052 #include <TDatabasePDG.h>
0053 #include <TObjArray.h>
0054 #include <TObjString.h>
0055
0056 #include <map>
0057 #include <vector>
0058 #include <algorithm> // for *min_element, *max_element
0059
0060 using std::cout;
0061 using std::cerr;
0062 using std::endl;
0063 using std::map;
0064 using std::vector;
0065
0066 namespace erhic {
0067
0068
0069 struct TProcessIdObjectCount {
0070
0071 TProcessIdObjectCount() {
0072 count = TProcessID::GetObjectCount();
0073 }
0074
0075
0076
0077
0078 ~TProcessIdObjectCount() {
0079 TProcessID::SetObjectCount(count);
0080 }
0081 int count;
0082 };
0083
0084 template<>
0085 bool EventFromAsciiFactory<erhic::EventHepMC>::AtEndOfEvent() const {return false;}
0086
0087 template<>
0088 void EventFromAsciiFactory<erhic::EventHepMC>::FindFirstEvent() {
0089
0090 }
0091
0092 template<>
0093 bool EventFromAsciiFactory<erhic::EventHepMC>::AddParticle() {
0094 try {
0095
0096
0097
0098 static std::shared_ptr<HepMC3::Reader> adapter = HepMC3::deduce_reader(*mInput);
0099
0100 if (mEvent.get()) {
0101 HepMC3::GenEvent evt(HepMC3::Units::GEV,HepMC3::Units::MM);
0102 adapter->read_event(evt);
0103 if ( adapter->failed() ) return false;
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 int particleindex;
0118 particleindex = 1;
0119
0120
0121 std::map < HepMC3::GenParticlePtr, int > hepmcp_index;
0122 hepmcp_index.clear();
0123
0124
0125
0126 auto beams = evt.beams();
0127
0128
0129
0130
0131
0132 assert ( beams.size() == 2 );
0133 auto hadron = beams.at(0);
0134 auto lepton = beams.at(1);
0135
0136
0137
0138
0139 if ( hadron->pid()==22 || lepton->pid()==22 ){
0140 if ( evt.particles().size() > 2 ){
0141 cout << "Warning: Treating the event as beam gas but found "
0142 << evt.particles().size() << " particles" << endl;
0143 }
0144 auto photon=hadron;
0145 if ( lepton->pid()==22 ) {
0146 std::swap (lepton, photon);
0147 }
0148
0149
0150
0151 auto beam_e_mom = lepton->momentum() + photon->momentum();
0152
0153
0154
0155
0156 auto beam_e = std::make_shared<HepMC3::GenParticle>( beam_e_mom, 11, 21 );
0157 auto v = lepton->production_vertex();
0158 v->add_particle_in (beam_e);
0159
0160
0161 auto pz_p = -10.0 *beam_e_mom.z();
0162 auto e_p = sqrt ( pow(pz_p,2) + pow(0.938,2) );
0163 HepMC3::FourVector beam_p_mom ( 0,0,pz_p, e_p);
0164 auto beam_p = std::make_shared<HepMC3::GenParticle>( beam_p_mom, 2212, 21 );
0165
0166 HandleHepmcParticle( beam_e, hepmcp_index, particleindex, mEvent );
0167 HandleHepmcParticle( beam_p, hepmcp_index, particleindex, mEvent );
0168
0169 HandleHepmcParticle( lepton, hepmcp_index, particleindex, mEvent );
0170 HandleHepmcParticle( photon, hepmcp_index, particleindex, mEvent );
0171
0172
0173 UpdateRuninfo( mObjectsToWriteAtTheEnd, evt );
0174
0175 return true;
0176 }
0177
0178
0179 auto pdgl = TDatabasePDG::Instance()->GetParticle( lepton->pid() );
0180 auto pdgh = TDatabasePDG::Instance()->GetParticle( hadron->pid() );
0181
0182
0183 bool b0islepton = (string(pdgl->ParticleClass()) == "Lepton");
0184 bool b1islepton = (string(pdgh->ParticleClass()) == "Lepton");
0185
0186
0187 if ( b0islepton == b1islepton ){
0188
0189
0190
0191
0192 HandleAllVertices(evt, hepmcp_index, particleindex, mEvent);
0193
0194
0195 UpdateRuninfo( mObjectsToWriteAtTheEnd, evt );
0196
0197 return true;
0198 }
0199
0200 if ( !b0islepton ) {
0201 std::swap (lepton, hadron);
0202 }
0203
0204
0205
0206
0207
0208 HepMC3::GenParticlePtr scatteredlepton=0;
0209 HepMC3::GenParticlePtr photon=0;
0210
0211
0212 if ( lepton->children().size() >2 || lepton->children().size()==0 ){
0213 cerr << "electron has " << lepton->children().size() << " daughters." << endl;
0214 throw std::runtime_error ("Wrong number of lepton daughters; should be 1 (lepton) or 2 (lepton+boson).");
0215 }
0216
0217
0218 if ( lepton->children().size() == 2 ){
0219 scatteredlepton = lepton->children().at(0);
0220 photon = lepton->children().at(1);
0221 if ( scatteredlepton->pid() != 22 && photon->pid() != 22 ){
0222 cerr << "lepton child 1 pid = " << scatteredlepton->pid() << endl;
0223 cerr << "lepton child 2 pid = " << photon->pid() << endl;
0224 throw std::runtime_error ("Found two beam lepton daughters, none or both of them a photon.");
0225 }
0226 if ( photon->pid() != 22 ){
0227 std::swap ( photon, scatteredlepton );
0228 }
0229 }
0230
0231
0232 if ( lepton->children().size() == 1 ){
0233 scatteredlepton = lepton->children().at(0);
0234 auto pdgs = TDatabasePDG::Instance()->GetParticle( scatteredlepton->pid() );
0235 if ( !TString(pdgs->ParticleClass()).Contains("Lepton") ){
0236 throw std::runtime_error ("Found one beam lepton daughter, and it is not a lepton.");
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 photon=std::make_shared<HepMC3::GenParticle>();
0248
0249 photon->set_pid( 0 );
0250 photon->set_status( 0 );
0251
0252 scatteredlepton->production_vertex()->add_particle_out(photon);
0253 }
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 bool foundbranch=true;
0265 while ( scatteredlepton->children().size() > 0 ){
0266 if ( !foundbranch ){
0267 throw std::runtime_error ("none of this lepton's children is a lepton.");
0268 }
0269 foundbranch=false;
0270 for ( auto& c : scatteredlepton->children() ){
0271 auto pdgl = TDatabasePDG::Instance()->GetParticle( c->pid() );
0272 if ( string(pdgl->ParticleClass()) == "Lepton" ){
0273
0274
0275
0276 scatteredlepton = c;
0277 foundbranch=true;
0278 break;
0279 }
0280 }
0281 }
0282
0283
0284 HandleHepmcParticle( lepton, hepmcp_index, particleindex, mEvent );
0285 HandleHepmcParticle( hadron, hepmcp_index, particleindex, mEvent );
0286 HandleHepmcParticle( scatteredlepton, hepmcp_index, particleindex, mEvent );
0287 HandleHepmcParticle( photon, hepmcp_index, particleindex, mEvent );
0288
0289
0290
0291
0292 HandleAllVertices(evt, hepmcp_index, particleindex, mEvent);
0293
0294
0295 UpdateRuninfo( mObjectsToWriteAtTheEnd, evt );
0296 }
0297
0298 auto finished = FinishEvent();
0299 return (finished==0);
0300 }
0301 catch(std::exception& error) {
0302 std::cerr << "Exception building particle: " << error.what() << std::endl;
0303 return false;
0304 }
0305 }
0306
0307 template<>
0308 erhic::EventHepMC* EventFromAsciiFactory<erhic::EventHepMC>::Create()
0309 {
0310 TProcessIdObjectCount objectCount;
0311 mEvent.reset(new erhic::EventHepMC());
0312 if (!AddParticle()) {
0313 mEvent.reset(nullptr);
0314 }
0315
0316 return mEvent.release();
0317 }
0318
0319
0320 void HandleHepmcParticle( const HepMC3::GenParticlePtr& p, std::map < HepMC3::GenParticlePtr, int >& hepmcp_index, int& particleindex, std::unique_ptr<erhic::EventHepMC>& mEvent ){
0321
0322 auto it = hepmcp_index.find(p);
0323 if ( it != hepmcp_index.end() ) return;
0324
0325
0326 ParticleMC particle;
0327 auto v = p->production_vertex();
0328 TVector3 vertex;
0329 if ( v ) vertex = TVector3(v->position().x(),v->position().y(),v->position().z());
0330
0331 particle.SetVertex(vertex);
0332
0333
0334 TLorentzVector lovec(p->momentum().x(),p->momentum().y(),p->momentum().z(),p->momentum().e());
0335 particle.Set4Vector(lovec);
0336
0337
0338
0339
0340 particle.SetId( p->pid() );
0341 particle.SetStatus(p->status());
0342
0343
0344 particle.SetIndex ( particleindex );
0345
0346
0347 hepmcp_index[p] = particleindex;
0348
0349 particleindex++;
0350
0351 particle.SetEvent(mEvent.get());
0352 mEvent->AddLast(&particle);
0353 }
0354
0355
0356 void HandleAllVertices( HepMC3::GenEvent& evt, std::map < HepMC3::GenParticlePtr, int >& hepmcp_index, int& particleindex, std::unique_ptr<erhic::EventHepMC>& mEvent ){
0357
0358
0359
0360 for (auto& v : evt.vertices() ){
0361 for (auto& p : v->particles_out() ) {
0362 HandleHepmcParticle( p, hepmcp_index, particleindex, mEvent );
0363 }
0364 }
0365
0366
0367
0368
0369
0370
0371
0372 for (auto& v : evt.vertices() ){
0373 for (auto& p : v->particles_out() ) {
0374
0375 int treeindex = hepmcp_index[p]-1;
0376 assert ( treeindex >=0 );
0377 auto track = mEvent->GetTrack(treeindex);
0378
0379
0380 vector<int> allparents;
0381 for (auto& parent : p->parents() ) {
0382 allparents.push_back( hepmcp_index[parent] );
0383 }
0384
0385
0386
0387 if ( allparents.size() == 1){
0388 track->SetParentIndex( allparents.at(0) );
0389 }
0390 if ( allparents.size() >= 2){
0391
0392 track->SetParentIndex( *min_element(allparents.begin(), allparents.end() ) );
0393 track->SetParentIndex1( *max_element(allparents.begin(), allparents.end() ) );
0394 }
0395
0396
0397 vector<int> allchildren;
0398 for (auto& child : p->children() ) {
0399 allchildren.push_back( hepmcp_index[child] );
0400 }
0401 if ( allchildren.size() == 1){
0402 track->SetChild1Index( allchildren.at(0) );
0403 }
0404 if ( allchildren.size() >= 2){
0405
0406 track->SetChild1Index( *min_element(allchildren.begin(), allchildren.end() ) );
0407 track->SetChildNIndex( *max_element(allchildren.begin(), allchildren.end() ) );
0408 }
0409 }
0410 }
0411 }
0412
0413
0414
0415 void UpdateRuninfo( std::vector<VirtualEventFactory::NamedObjects>& mObjectsToWriteAtTheEnd,
0416 const HepMC3::GenEvent& evt ){
0417
0418
0419 TString xsec = "";
0420 TString xsecerr = "";
0421 if ( auto xsecinfo=evt.cross_section() ){
0422
0423 xsec += xsecinfo->xsec();
0424 xsecerr += xsecinfo->xsec_err();
0425 }
0426 TObjString* Xsec;
0427 TObjString* Xsecerr;
0428
0429
0430
0431
0432
0433
0434
0435 if ( mObjectsToWriteAtTheEnd.size() == 0 ){
0436 Xsec = new TObjString;
0437 Xsecerr = new TObjString;
0438 mObjectsToWriteAtTheEnd.push_back ( VirtualEventFactory::NamedObjects( "crossSection", Xsec) );
0439 mObjectsToWriteAtTheEnd.push_back ( VirtualEventFactory::NamedObjects( "crossSectionError", Xsecerr) );
0440
0441
0442
0443
0444 }
0445 Xsec = (TObjString*) mObjectsToWriteAtTheEnd.at(0).second;
0446 Xsec->String() = xsec;
0447 Xsecerr = (TObjString*) mObjectsToWriteAtTheEnd.at(1).second;
0448 Xsecerr->String() = xsecerr;
0449
0450
0451
0452
0453 }
0454
0455 }
0456
0457 namespace {
0458
0459
0460 erhic::EventFromAsciiFactory<erhic::EventHepMC> eh;
0461 }