9 #include "HepPDT/ParticleID.hh" 12 #include "G4HEPEvtParticle.hh" 14 #include "G4ParticleDefinition.hh" 15 #include "G4PhysicalConstants.hh" 16 #include "G4SystemOfUnits.hh" 17 #include "G4UnitsTable.hh" 24 : fPCuts(
p.getParameter<
bool>(
"ApplyPCuts")),
25 fPtransCut(
p.getParameter<
bool>(
"ApplyPtransCut")),
26 fEtaCuts(
p.getParameter<
bool>(
"ApplyEtaCuts")),
27 fPhiCuts(
p.getParameter<
bool>(
"ApplyPhiCuts")),
28 fFixG4Primary(
p.getParameter<
bool>(
"FixG4Primary")),
29 theMinPhiCut(
p.getParameter<double>(
"MinPhiCut")),
30 theMaxPhiCut(
p.getParameter<double>(
"MaxPhiCut")),
31 theMinEtaCut(
p.getParameter<double>(
"MinEtaCut")),
32 theMaxEtaCut(
p.getParameter<double>(
"MaxEtaCut")),
33 theMinPCut(
p.getParameter<double>(
"MinPCut")),
34 theMaxPCut(
p.getParameter<double>(
"MaxPCut")),
35 theEtaCutForHector(
p.getParameter<double>(
"EtaCutForHector")),
36 verbose(
p.getUntrackedParameter<
int>(
"Verbosity", 0)),
46 bool lumi =
p.getParameter<
bool>(
"ApplyLumiMonitorCuts");
51 double theRDecLenCut =
p.getParameter<
double>(
"RDecLenCut") * CLHEP::cm;
56 double theDecLenCut =
p.getParameter<
double>(
"LDecLenCut") * CLHEP::cm;
63 if (
p.exists(
"PDGselection")) {
69 ss <<
"SimG4Core/Generator: ";
71 ss <<
" Selecting only PDG ID = ";
73 ss <<
" Filtering out PDG ID = ";
89 edm::LogVerbatim(
"SimG4CoreGenerator") <<
"SimG4Core/Generator: Rdecaycut= " << theRDecLenCut / CLHEP::cm
91 <<
"Z_min= " <<
Z_lmin / CLHEP::cm <<
" cm; Z_max= " <<
Z_lmax / CLHEP::cm
95 <<
" Z_hector = " <<
Z_hector / CLHEP::cm <<
" cm\n" 99 <<
" LumiMonitorCut: " <<
lumi;
116 if (*(evt->vertices_begin()) ==
nullptr) {
117 std::stringstream
ss;
118 ss <<
"SimG4Core/Generator: in event " << g4evt->GetEventID() <<
" Corrupted Event - GenEvent with no vertex \n";
122 if (!evt->weights().empty()) {
124 for (
unsigned int iw = 1; iw < evt->weights().size(); ++iw) {
126 if (evt->weights()[iw] <= 0)
132 if (
vtx_ !=
nullptr) {
136 (*(evt->vertices_begin()))->position().y(),
137 (*(evt->vertices_begin()))->position().z(),
138 (*(evt->vertices_begin()))->position().t());
143 unsigned int ng4vtx = 0;
144 unsigned int ng4par = 0;
146 for (HepMC::GenEvent::vertex_const_iterator vitr = evt->vertices_begin(); vitr != evt->vertices_end(); ++vitr) {
152 HepMC::GenVertex::particle_iterator pitr;
158 int status = (*pitr)->status();
159 int pdg = (*pitr)->pdg_id();
181 LogDebug(
"SimG4CoreGenerator") <<
"GenVertex barcode = " << (*vitr)->barcode()
182 <<
" selected for GenParticle barcode = " << (*pitr)->barcode();
189 if ((*pitr)->end_vertex() !=
nullptr) {
190 double xx = (*pitr)->end_vertex()->position().x();
191 double yy = (*pitr)->end_vertex()->position().y();
197 <<
"GenVertex barcode = " << (*vitr)->barcode()
198 <<
" selected for GenParticle barcode = " << (*pitr)->barcode() <<
" radius = " <<
std::sqrt(r_dd);
216 double x1 = (*vitr)->position().x() * CLHEP::mm;
217 double y1 = (*vitr)->position().y() * CLHEP::mm;
218 double z1 = (*vitr)->position().z() * CLHEP::mm;
219 double t1 = (*vitr)->position().t() * CLHEP::mm / CLHEP::c_light;
221 G4PrimaryVertex *g4vtx =
new G4PrimaryVertex(
x1,
y1, z1,
t1);
224 int status = (*pitr)->status();
225 int pdg = (*pitr)->pdg_id();
226 bool hasDecayVertex = (
nullptr != (*pitr)->end_vertex());
234 <<
" Skiped GenParticle barcode= " << (*pitr)->barcode() <<
" PDGid= " <<
pdg <<
" status= " <<
status 236 <<
" isInTheList: " << isInTheList <<
" hasDecayVertex: " << hasDecayVertex;
243 <<
"Generator: pdg= " <<
pdg <<
" status= " <<
status <<
" hasPreDefinedDecay: " << hasDecayVertex
250 status = hasDecayVertex ? 2 : 1;
257 if (2 ==
status && !hasDecayVertex) {
259 << g4evt->GetEventID() <<
" a particle " 260 <<
" pdgid= " <<
pdg <<
" has status=2 but has no decay vertex, so will be fully tracked by Geant4";
267 double decay_length = 0.0;
269 x2 = (*pitr)->end_vertex()->position().x();
270 y2 = (*pitr)->end_vertex()->position().y();
271 z2 = (*pitr)->end_vertex()->position().z();
277 double px = (*pitr)->momentum().px();
278 double py = (*pitr)->momentum().py();
279 double pz = (*pitr)->momentum().pz();
289 const double minTan = 1.e-20;
292 double del = (zimpact - z1) / pz;
296 double rimpact2 = ximpact * ximpact + yimpact * yimpact;
299 LogDebug(
"SimG4CoreGenerator") <<
"Processing GenParticle barcode= " << (*pitr)->barcode() <<
" pdg= " <<
pdg 300 <<
" status= " << (*pitr)->status() <<
" st= " <<
status 301 <<
" rimpact(cm)= " <<
std::sqrt(rimpact2) / cm
302 <<
" zimpact(cm)= " << zimpact / cm <<
" ptot(GeV)= " << ptot
303 <<
" pz(GeV)= " << pz;
312 <<
"GenParticle barcode = " << (*pitr)->barcode() <<
" very forward; to be added: " << toBeAdded;
323 double phi =
p.phi();
337 if (
std::abs(pz) >= minTan * ptot) {
338 if ((zi >=
Z_lmax) & (pz < 0.0)) {
340 }
else if ((zi <=
Z_lmin) & (pz > 0.0)) {
349 double del = (zi - z1) / pz;
364 <<
"GenParticle barcode = " << (*pitr)->barcode() <<
" passed case 1";
372 edm::LogVerbatim(
"SimG4CoreGenerator") <<
"GenParticle barcode = " << (*pitr)->barcode() <<
" passed case 2" 373 <<
" decay_length(cm)= " << decay_length / CLHEP::cm;
377 G4PrimaryParticle *g4prim =
new G4PrimaryParticle(
pdg,
px * GeV,
py * GeV, pz * GeV);
379 if (g4prim->GetG4code() !=
nullptr) {
380 g4prim->SetMass(g4prim->GetG4code()->GetPDGMass());
381 double charge = g4prim->GetG4code()->GetPDGCharge();
388 g4prim->SetCharge(
charge);
394 setGenId(g4prim, (*pitr)->barcode());
403 g4vtx->SetPrimary(g4prim);
404 edm::LogVerbatim(
"SimG4CoreGenerator") <<
" " << ng4par <<
". new Geant4 particle pdg= " <<
pdg 406 <<
" status= " <<
status <<
"; dir= " << g4prim->GetMomentumDirection();
412 g4evt->AddPrimaryVertex(g4vtx);
419 G4PrimaryVertex *g4vtx =
new G4PrimaryVertex(0.0, 0.0, 0.0, 0.0);
423 g4evt->AddPrimaryVertex(g4vtx);
426 edm::LogVerbatim(
"SimG4CoreGenerator") <<
"The list of Geant4 primaries includes " << ng4par <<
" particles in " 427 << ng4vtx <<
" vertex";
433 LogDebug(
"SimG4CoreGenerator") <<
"Special case of long decay length \n" 434 <<
"Assign daughters with to mother with decaylength=" << decaylength / cm <<
" cm";
439 double proper_time = decaylength / (
p.Beta() *
p.Gamma() * c_light);
440 g4p->SetProperTime(proper_time);
443 LogDebug(
"SimG4CoreGenerator") <<
" px= " <<
p.px() <<
" py= " <<
p.py() <<
" pz= " <<
p.pz() <<
" e= " <<
p.e()
444 <<
" beta= " <<
p.Beta() <<
" gamma= " <<
p.Gamma()
445 <<
" Proper time= " << proper_time / ns <<
" ns";
450 double x1 = vp->end_vertex()->position().x();
451 double y1 = vp->end_vertex()->position().y();
452 double z1 = vp->end_vertex()->position().z();
454 for (HepMC::GenVertex::particle_iterator vpdec = vp->end_vertex()->particles_begin(
HepMC::children);
459 (*vpdec)->momentum().px(), (*vpdec)->momentum().py(), (*vpdec)->momentum().pz(), (*vpdec)->momentum().e());
462 G4PrimaryParticle *g4daught =
463 new G4PrimaryParticle((*vpdec)->pdg_id(), pdec.x() * CLHEP::GeV, pdec.y() * CLHEP::GeV, pdec.z() * CLHEP::GeV);
465 if (g4daught->GetG4code() !=
nullptr) {
466 g4daught->SetMass(g4daught->GetG4code()->GetPDGMass());
467 g4daught->SetCharge(g4daught->GetG4code()->GetPDGCharge());
472 setGenId(g4daught, (*vpdec)->barcode());
474 int status = (*vpdec)->status();
476 LogDebug(
"SimG4CoreGenerator::particleAssignDaughters")
477 <<
"Assigning a " << (*vpdec)->pdg_id() <<
" as daughter of a " << vp->pdg_id() <<
" status=" <<
status;
483 if ((
status == 2 || checkStatus) && (*vpdec)->end_vertex() !=
nullptr) {
484 double x2 = (*vpdec)->end_vertex()->position().x();
485 double y2 = (*vpdec)->end_vertex()->position().y();
486 double z2 = (*vpdec)->end_vertex()->position().z();
490 (*vpdec)->set_status(1000 +
status);
491 g4p->SetDaughter(g4daught);
501 double ptot =
p.mag();
502 if (
fPCuts && (ptot < theMinPCut * CLHEP::GeV || ptot >
theMaxPCut * CLHEP::GeV)) {
507 if (ptot < pz + 1.
e-10) {
511 double eta = 0.5 * G4Log((ptot + pz) / (ptot - pz));
518 double phi =
p.phi();
525 LogDebug(
"SimG4CoreGenerator") <<
"Generator ptot(GeV)= " << ptot / GeV <<
" eta= " <<
p.eta()
526 <<
" phi= " <<
p.phi() <<
" Flag= " <<
flag;
542 int charge = pid.threeCharge();
557 int i = g4evt->GetNumberOfPrimaryVertex();
558 for (HepMC::GenEvent::particle_const_iterator it = evt->particles_begin(); it != evt->particles_end(); ++it) {
563 if (
gp->status() != 1)
566 int pdg =
gp->pdg_id();
567 G4PrimaryParticle *g4p =
new G4PrimaryParticle(
568 pdg,
gp->momentum().px() * CLHEP::GeV,
gp->momentum().py() * CLHEP::GeV,
gp->momentum().pz() * CLHEP::GeV);
569 if (g4p->GetG4code() !=
nullptr) {
570 g4p->SetMass(g4p->GetG4code()->GetPDGMass());
571 g4p->SetCharge(g4p->GetG4code()->GetPDGCharge());
574 G4PrimaryVertex *
v =
new G4PrimaryVertex(
gp->production_vertex()->position().x() * CLHEP::mm,
575 gp->production_vertex()->position().y() * CLHEP::mm,
576 gp->production_vertex()->position().z() * CLHEP::mm,
577 gp->production_vertex()->position().t() * CLHEP::mm / CLHEP::c_light);
579 g4evt->AddPrimaryVertex(
v);
Log< level::Info, true > LogVerbatim
bool isExoticNonDetectable(int pdgcode) const
void nonCentralEvent2G4(const HepMC::GenEvent *g, G4Event *e)
double theEtaCutForHector
void HepMC2G4(const HepMC::GenEvent *g, G4Event *e)
Generator(const edm::ParameterSet &p)
bool isExotic(int pdgcode) const
bool isGoodForLumiMonitor(const HepMC::GenParticle *) const
void particleAssignDaughters(G4PrimaryParticle *p, HepMC::GenParticle *hp, double length)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
LumiMonitorFilter * fLumiFilter
bool particlePassesPrimaryCuts(const G4ThreeVector &p) const
Abs< T >::type abs(const T &t)
math::XYZTLorentzVector * vtx_
void setGenId(G4PrimaryParticle *p, int id) const
std::vector< int > pdgFilter
Log< level::Warning, false > LogWarning
bool IsInTheFilterList(int pdgcode) const