void Output_Delphes::AnalyseParticles(ExRootTreeBranch *branch, const HepMC::GenEvent& evt) { TRootC::GenParticle *element; TLorentzVector momentum; Double_t signPz; ReadStats(); for(int n=1; n<=evt.particles_size(); n++) { int mo1, mo2, da1, da2, status, pid; getStatsFromTuple(mo1,mo2,da1,da2,status,pid,n); element = static_cast<TRootC::GenParticle*>(branch->NewEntry()); element->PID = pid; element->Status = status; element->M1 = mo1 - 1; // added -1 as the numbering in the tree starts from 0 element->M2 = mo2 - 1; element->D1 = da1 - 1; element->D2 = da2 - 1; element->E = index_to_particle[n]->momentum().e(); element->Px = index_to_particle[n]->momentum().px(); element->Py = index_to_particle[n]->momentum().py(); element->Pz = index_to_particle[n]->momentum().pz(); element->PT = sqrt(pow(element->Px,2)+pow(element->Py,2)); momentum.SetPxPyPzE(element->Px, element->Py, element->Pz, element->E); signPz = (element->Pz >= 0.0) ? 1.0 : -1.0; element->Eta = element->PT < 1e-6 ? signPz*999.9 : momentum.Eta(); element->Phi = index_to_particle[n]->momentum().phi(); HepMC::GenVertex* vrtI = (index_to_particle[n])->production_vertex(); HepMC::GenVertex::particles_in_const_iterator partI; if(vrtI) { element->T = vrtI->position().t(); element->X = vrtI->position().x(); element->Y = vrtI->position().y(); element->Z = vrtI->position().z(); } else { element->T = 0.; element->X = 0.; element->Y = 0.; element->Z = 0.; } } }
StatusCode EDMToHepMCConverter::execute() { const fcc::MCParticleCollection* particles = m_genphandle.get(); // ownership of event given to data service at the end of execute HepMC::GenEvent* event = new HepMC::GenEvent; // conversion of units to EDM standard units: // First cover the case that hepMC file is not in expected units and then convert to EDM default double hepmc2EdmLength = conversion_factor(event->length_unit(), gen::hepmcdefault::length) * gen::hepmc2edm::length; double hepmc2EdmEnergy = conversion_factor(event->momentum_unit(), gen::hepmcdefault::energy) * gen::hepmc2edm::energy; for (auto p : *(particles)) { if (p.status() == 1) { // only final state particles GenParticle* pHepMC = new GenParticle(HepMC::FourVector(p.p4().px, p.p4().py, p.p4().pz, p.p4().mass / hepmc2EdmEnergy), p.pdgId(), p.status()); // hepmc status code for final state particle fcc::ConstGenVertex vStart = p.startVertex(); if (p.startVertex().isAvailable()) { HepMC::GenVertex* v = new HepMC::GenVertex(HepMC::FourVector(vStart.position().x / hepmc2EdmLength, vStart.position().y / hepmc2EdmLength, vStart.position().z / hepmc2EdmLength, vStart.ctau() / Gaudi::Units::c_light / hepmc2EdmLength)); v->add_particle_out(pHepMC); event->add_vertex(v); } } } m_hepmchandle.put(event); return StatusCode::SUCCESS; }
StatusCode ConstPtParticleGun::getNextEvent(HepMC::GenEvent& theEvent) { Gaudi::LorentzVector theFourMomentum; Gaudi::LorentzVector origin; // note: pgdid is set in function generateParticle int thePdgId; generateParticle(theFourMomentum, origin, thePdgId); // create HepMC Vertex -- // by calling add_vertex(), the hepmc event is given ownership of the vertex HepMC::GenVertex* v = new HepMC::GenVertex(HepMC::FourVector(origin.X(), origin.Y(), origin.Z(), origin.T())); // create HepMC particle -- // by calling add_particle_out(), the hepmc vertex is given ownership of the particle HepMC::GenParticle* p = new HepMC::GenParticle( HepMC::FourVector(theFourMomentum.Px(), theFourMomentum.Py(), theFourMomentum.Pz(), theFourMomentum.E()), thePdgId, 1); // hepmc status code for final state particle v->add_particle_out(p); theEvent.add_vertex(v); theEvent.set_signal_process_vertex(v); return StatusCode::SUCCESS; }
StatusCode HepMCToEDMConverter::execute() { const HepMC::GenEvent* event = m_hepmchandle.get(); fcc::MCParticleCollection* particles = new fcc::MCParticleCollection(); fcc::GenVertexCollection* vertices = new fcc::GenVertexCollection(); // conversion of units to EDM standard units: // First cover the case that hepMC file is not in expected units and then convert to EDM default double hepmc2EdmLength = HepMC::Units::conversion_factor(event->length_unit(), gen::hepmcdefault::length) * gen::hepmc2edm::length; double hepmc2EdmEnergy = HepMC::Units::conversion_factor(event->momentum_unit(), gen::hepmcdefault::energy) * gen::hepmc2edm::energy; // bookkeeping of particle / vertex relations std::unordered_map<const HepMC::GenVertex*, fcc::GenVertex> hepmcToEdmVertexMap; HepMC::FourVector tmp; /// temp variable for the transfer of position / momentom // iterate over particles in event for (auto particle_i = event->particles_begin(); particle_i != event->particles_end(); ++particle_i) { // if there is a list of statuses to filter: filter by status if(std::find(m_hepmcStatusList.begin(), m_hepmcStatusList.end(), (*particle_i)->status()) == m_hepmcStatusList.end() && m_hepmcStatusList.size() > 0) continue; // create edm fcc::MCParticle particle = particles->create(); // set mcparticle data members particle.pdgId((*particle_i)->pdg_id()); particle.status((*particle_i)->status()); /// lookup charge in particle properties HepPDT::ParticleID particleID((*particle_i)->pdg_id()); particle.charge(particleID.charge()); auto& p4 = particle.p4(); tmp = (*particle_i)->momentum(); p4.px = tmp.px() * hepmc2EdmEnergy; p4.py = tmp.py() * hepmc2EdmEnergy; p4.pz = tmp.pz() * hepmc2EdmEnergy; p4.mass = (*particle_i)->generated_mass() * hepmc2EdmEnergy; /// create production vertex, if it has not already been created and logged in the map HepMC::GenVertex* productionVertex = (*particle_i)->production_vertex(); if (nullptr != productionVertex) { if (hepmcToEdmVertexMap.find(productionVertex) != hepmcToEdmVertexMap.end()) { // vertex already in map, no need to create a new one particle.startVertex(hepmcToEdmVertexMap[productionVertex]); } else { tmp = productionVertex->position(); auto vertex = vertices->create(); auto& position = vertex.position(); position.x = tmp.x() * hepmc2EdmLength; position.y = tmp.y() * hepmc2EdmLength; position.z = tmp.z() * hepmc2EdmLength; vertex.ctau(tmp.t() * Gaudi::Units::c_light * hepmc2EdmLength); // is ctau like this? // add vertex to map for further particles hepmcToEdmVertexMap.insert({productionVertex, vertex}); particle.startVertex(vertex); } } /// create decay vertex, if it has not already been created and logged in the map HepMC::GenVertex* decayVertex = (*particle_i)->end_vertex(); if (nullptr != decayVertex) { if (hepmcToEdmVertexMap.find(decayVertex) != hepmcToEdmVertexMap.end()) { // vertex already in map, no need to create a new one particle.endVertex(hepmcToEdmVertexMap[decayVertex]); } else { tmp = decayVertex->position(); auto vertex = vertices->create(); auto& position = vertex.position(); position.x = tmp.x() * hepmc2EdmLength; position.y = tmp.y() * hepmc2EdmLength; position.z = tmp.z() * hepmc2EdmLength; vertex.ctau(tmp.t() * Gaudi::Units::c_light * hepmc2EdmLength); // is ctau like this? // add vertex to map for further particles hepmcToEdmVertexMap.insert({decayVertex, vertex}); particle.endVertex(vertex); } } } // particle loop m_genphandle.put(particles); m_genvhandle.put(vertices); return StatusCode::SUCCESS; }
int PHSartre::process_event(PHCompositeNode *topNode) { if (verbosity > 1) cout << "PHSartre::process_event - event: " << _eventcount << endl; bool passedTrigger = false; Event *event = NULL; TLorentzVector *eIn = NULL; TLorentzVector *pIn = NULL; TLorentzVector *eOut = NULL; TLorentzVector *gamma = NULL; TLorentzVector *vm = NULL; TLorentzVector *PomOut = NULL; TLorentzVector *pOut = NULL; TLorentzVector *vmDecay1 = NULL; TLorentzVector *vmDecay2 = NULL; unsigned int preVMDecaySize = 0; while (!passedTrigger) { ++_gencount; // Generate a Sartre event event = _sartre->generateEvent(); // // If Sartre is run in UPC mode, half of the events needs to be // rotated around and axis perpendicular to z: // (only for symmetric events) // if(settings->UPC() and settings->A()==settings->UPCA()){ randomlyReverseBeams(event); } // for sPHENIX/RHIC p+Au // (see comments in ReverseBeams) // reverse when the proton emits the virtual photon if(settings->UPC() and settings->A()==197){ ReverseBeams(event); } // Set pointers to the parts of the event we will need: eIn = &event->particles[0].p; pIn = &event->particles[1].p; eOut = &event->particles[2].p; gamma = &event->particles[3].p; vm = &event->particles[4].p; PomOut = &event->particles[5].p; pOut = &event->particles[6].p; // To allow the triggering to work properly, we need to decay the vector meson here preVMDecaySize = event->particles.size(); if(doPerformDecay) { if( decay->SetDecay(*vm, 2, daughterMasses) ){ double weight = decay->Generate(); // weight is always 1 here if ( (weight-1) > FLT_EPSILON) { cout << "PHSartre: Warning decay weight != 1, weight = " << weight << endl; } TLorentzVector *vmDaughter1 = decay->GetDecay(0); TLorentzVector *vmDaughter2 = decay->GetDecay(1); event->particles[4].status = 2; // set VM status Particle vmDC1; vmDC1.index = event->particles.size(); vmDC1.pdgId = daughterID; vmDC1.status = 1; // final state vmDC1.p = *vmDaughter1; vmDC1.parents.push_back(4); event->particles.push_back(vmDC1); vmDecay1 = &event->particles[event->particles.size()-1].p; Particle vmDC2; vmDC2.index = event->particles.size(); vmDC2.pdgId = -daughterID; vmDC2.status = 1; // final state vmDC2.p = *vmDaughter2; vmDC2.parents.push_back(4); event->particles.push_back(vmDC2); vmDecay2 = &event->particles[event->particles.size()-1].p; } else { cout << "PHSartre: WARNING: Kinematics of Vector Meson does not allow decay!" << endl; } } // test trigger logic bool andScoreKeeper = true; if (verbosity > 2) { cout << "PHSartre::process_event - triggersize: " << _registeredTriggers.size() << endl; } for (unsigned int tr = 0; tr < _registeredTriggers.size(); tr++) { bool trigResult = _registeredTriggers[tr]->Apply(event); if (verbosity > 2) { cout << "PHSartre::process_event trigger: " << _registeredTriggers[tr]->GetName() << " " << trigResult << endl; } if (_triggersOR && trigResult) { passedTrigger = true; break; } else if (_triggersAND) { andScoreKeeper &= trigResult; } if (verbosity > 2 && !passedTrigger) { cout << "PHSartre::process_event - failed trigger: " << _registeredTriggers[tr]->GetName() << endl; } } if ((andScoreKeeper && _triggersAND) || (_registeredTriggers.size() == 0)) { passedTrigger = true; } } // fill HepMC object with event HepMC::GenEvent *genevent = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM); // add some information to the event genevent->set_event_number(_eventcount); // Set the PDF information HepMC::PdfInfo pdfinfo; pdfinfo.set_scalePDF(event->Q2); genevent->set_pdf_info(pdfinfo); // We would also like to save: // // event->t; // event->x; // event->y; // event->s; // event->W; // event->xpom; // (event->polarization == transverse ? 0 : 1); // (event->diffractiveMode == coherent ? 0 : 1); // // but there doesn't seem to be a good place to do so // within the HepMC event information? // // t, W and Q^2 form a minial set of good variables for diffractive events // Maybe what I do is record the input particles to the event at the HepMC // vertices and reconstruct the kinematics from there? // Create HepMC vertices and add final state particles to them // First, the emitter(electron)-virtual photon vertex: HepMC::GenVertex* egammavtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0)); genevent->add_vertex(egammavtx); egammavtx->add_particle_in( new HepMC::GenParticle( CLHEP::HepLorentzVector(eIn->Px(), eIn->Py(), eIn->Pz(), eIn->E()), event->particles[0].pdgId, 3 ) ); HepMC::GenParticle *hgamma = new HepMC::GenParticle( CLHEP::HepLorentzVector(gamma->Px(), gamma->Py(), gamma->Pz(), gamma->E()), event->particles[3].pdgId, 3 ); egammavtx->add_particle_out(hgamma); egammavtx->add_particle_out( new HepMC::GenParticle( CLHEP::HepLorentzVector(eOut->Px(), eOut->Py(), eOut->Pz(), eOut->E()), event->particles[2].pdgId, 1 ) ); // Next, the hadron-pomeron vertex: HepMC::GenVertex* ppomvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0)); genevent->add_vertex(ppomvtx); ppomvtx->add_particle_in( new HepMC::GenParticle( CLHEP::HepLorentzVector(pIn->Px(), pIn->Py(), pIn->Pz(), pIn->E()), event->particles[1].pdgId, 3 ) ); HepMC::GenParticle *hPomOut = new HepMC::GenParticle( CLHEP::HepLorentzVector(PomOut->Px(), PomOut->Py(), PomOut->Pz(), PomOut->E()), event->particles[5].pdgId, 3 ); ppomvtx->add_particle_out(hPomOut); // If this is a nuclear breakup, add in the nuclear fragments // Otherwise, add in the outgoing hadron //If the event is incoherent, and nuclear breakup is enabled, fill the remnants to the tree if(settings->enableNuclearBreakup() and event->diffractiveMode == incoherent){ for(unsigned int iParticle=7; iParticle < preVMDecaySize; iParticle++){ if(event->particles[iParticle].status == 1) { // Final-state particle const Particle& particle = event->particles[iParticle]; ppomvtx->add_particle_out( new HepMC::GenParticle( CLHEP::HepLorentzVector(particle.p.Px(), particle.p.Py(), particle.p.Pz(), particle.p.E()), particle.pdgId, 1 ) ); } } } else{ ppomvtx->add_particle_out( new HepMC::GenParticle( CLHEP::HepLorentzVector(pOut->Px(), pOut->Py(), pOut->Pz(), pOut->E()), event->particles[6].pdgId, 1 ) ); } // The Pomeron-Photon vertex HepMC::GenVertex* gammapomvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0)); genevent->add_vertex(gammapomvtx); gammapomvtx->add_particle_in(hgamma); gammapomvtx->add_particle_in(hPomOut); int isVMFinal = 1; if(doPerformDecay) isVMFinal = 2; HepMC::GenParticle *hvm = new HepMC::GenParticle( CLHEP::HepLorentzVector(vm->Px(), vm->Py(), vm->Pz(), vm->E()), event->particles[4].pdgId, isVMFinal ) ; gammapomvtx->add_particle_out( hvm ); // Add the VM decay to the event if(doPerformDecay) { if(vmDecay1 && vmDecay2){ HepMC::GenVertex* fvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0)); genevent->add_vertex(fvtx); fvtx->add_particle_in( hvm ); fvtx->add_particle_out( new HepMC::GenParticle( CLHEP::HepLorentzVector(vmDecay1->Px(), vmDecay1->Py(), vmDecay1->Pz(), vmDecay1->E()), daughterID, 1 ) ); fvtx->add_particle_out( new HepMC::GenParticle( CLHEP::HepLorentzVector(vmDecay2->Px(), vmDecay2->Py(), vmDecay2->Pz(), vmDecay2->E()), -daughterID, 1 ) ); } else { cout << "PHSartre: WARNING: Kinematics of Vector Meson does not allow decay!" << endl; } } // pass HepMC to PHNode PHHepMCGenEvent * success = hepmc_helper . insert_event(genevent); if (!success) { cout << "PHSartre::process_event - Failed to add event to HepMC record!" << endl; return Fun4AllReturnCodes::ABORTRUN; } // print outs if (verbosity > 2) cout << "PHSartre::process_event - FINISHED WHOLE EVENT" << endl; ++_eventcount; return Fun4AllReturnCodes::EVENT_OK; }
bool HepMC2_Interface::Sherpa2HepMC(ATOOLS::Blob_List *const blobs, HepMC::GenEvent& event, double weight) { #ifdef USING__HEPMC2__UNITS event.use_units(HepMC::Units::GEV, HepMC::Units::MM); #endif event.set_event_number(ATOOLS::rpa->gen.NumberOfGeneratedEvents()); size_t decid(11); std::map<size_t,size_t> decids; Blob *sp(blobs->FindFirst(btp::Signal_Process)); if (sp) { Blob_Data_Base *info((*sp)["Decay_Info"]); if (info) { DecayInfo_Vector decs(info->Get<DecayInfo_Vector>()); for (size_t i(0);i<decs.size();++i) decids[decs[i]->m_id]=++decid; } } m_blob2genvertex.clear(); m_particle2genparticle.clear(); HepMC::GenVertex * vertex; std::vector<HepMC::GenParticle*> beamparticles; for (ATOOLS::Blob_List::iterator blit=blobs->begin(); blit!=blobs->end();++blit) { if (Sherpa2HepMC(*(blit),vertex,decids)) { event.add_vertex(vertex); if ((*blit)->Type()==ATOOLS::btp::Signal_Process) { if ((**blit)["NLO_subeventlist"]) { THROW(fatal_error,"Events containing correlated subtraction events" +std::string(" cannot be translated into the full HepMC event") +std::string(" format.\n") +std::string(" Try 'EVENT_OUTPUT=HepMC_Short' instead.")); } event.set_signal_process_vertex(vertex); if((*blit)->NInP()==2) { kf_code fl1=(*blit)->InParticle(0)->Flav().HepEvt(); kf_code fl2=(*blit)->InParticle(1)->Flav().HepEvt(); double x1=(*blit)->InParticle(0)->Momentum()[0]/rpa->gen.PBeam(0)[0]; double x2=(*blit)->InParticle(1)->Momentum()[0]/rpa->gen.PBeam(1)[0]; double q(0.0), p1(0.0), p2(0.0); Blob_Data_Base *facscale((**blit)["Factorisation_Scale"]); if (facscale) q=sqrt(facscale->Get<double>()); Blob_Data_Base *xf1((**blit)["XF1"]); Blob_Data_Base *xf2((**blit)["XF2"]); if (xf1) p1=xf1->Get<double>(); if (xf2) p2=xf2->Get<double>(); HepMC::PdfInfo pdfinfo(fl1, fl2, x1, x2, q, p1, p2); event.set_pdf_info(pdfinfo); } } else if ((*blit)->Type()==ATOOLS::btp::Beam || (*blit)->Type()==ATOOLS::btp::Bunch) { for (HepMC::GenVertex::particles_in_const_iterator pit=vertex->particles_in_const_begin(); pit!=vertex->particles_in_const_end(); ++pit) { if ((*pit)->production_vertex()==NULL) { beamparticles.push_back(*pit); } } } } } if (beamparticles.size()==2) { event.set_beam_particles(beamparticles[0],beamparticles[1]); } std::vector<double> weights; weights.push_back(weight); if (sp) { Blob_Data_Base *info((*sp)["MEWeight"]); if (!info) THROW(fatal_error,"Missing weight info."); double meweight(info->Get<double>()); weights.push_back(meweight); Blob_Data_Base *ofni((*sp)["Weight_Norm"]); if (!ofni) THROW(fatal_error,"Missing weight normalisation."); double weightnorm(ofni->Get<double>()); weights.push_back(weightnorm); ofni=(*sp)["Trials"]; if (!ofni) THROW(fatal_error,"Missing nof trials."); double trials(ofni->Get<double>()); weights.push_back(trials); } event.weights()=weights; return true; }