File indexing completed on 2024-12-01 23:40:41
0001 #include "SimG4Core/Generators/interface/Generator3.h"
0002 #include "SimG4Core/Generators/interface/HepMCParticle.h"
0003 #include "SimG4Core/Generators/interface/LumiMonitorFilter.h"
0004
0005 #include "SimG4Core/Notification/interface/SimG4Exception.h"
0006
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008
0009 #include "HepPDT/ParticleID.hh"
0010
0011 #include "G4Event.hh"
0012 #include "G4HEPEvtParticle.hh"
0013 #include "G4Log.hh"
0014 #include "G4ParticleDefinition.hh"
0015 #include "G4PhysicalConstants.hh"
0016 #include <CLHEP/Units/SystemOfUnits.h>
0017 #include "G4UnitsTable.hh"
0018
0019 #include "HepMC3/Print.h"
0020
0021 #include <sstream>
0022
0023 using namespace edm;
0024
0025 Generator3::Generator3(const ParameterSet &p)
0026 : fPCuts(p.getParameter<bool>("ApplyPCuts")),
0027 fPtransCut(p.getParameter<bool>("ApplyPtransCut")),
0028 fEtaCuts(p.getParameter<bool>("ApplyEtaCuts")),
0029 fPhiCuts(p.getParameter<bool>("ApplyPhiCuts")),
0030 theMinPhiCut(p.getParameter<double>("MinPhiCut")),
0031 theMaxPhiCut(p.getParameter<double>("MaxPhiCut")),
0032 theMinEtaCut(p.getParameter<double>("MinEtaCut")),
0033 theMaxEtaCut(p.getParameter<double>("MaxEtaCut")),
0034 theMinPCut(p.getParameter<double>("MinPCut")),
0035 theMaxPCut(p.getParameter<double>("MaxPCut")),
0036 theEtaCutForHector(p.getParameter<double>("EtaCutForHector")),
0037 verbose(p.getUntrackedParameter<int>("Verbosity", 0)),
0038 fLumiFilter(nullptr),
0039 evt_(nullptr),
0040 vtx_(nullptr),
0041 weight_(0),
0042 Z_lmin(0),
0043 Z_lmax(0),
0044 Z_hector(0),
0045 pdgFilterSel(false),
0046 fPDGFilter(false) {
0047 bool lumi = p.getParameter<bool>("ApplyLumiMonitorCuts");
0048 if (lumi) {
0049 fLumiFilter = new LumiMonitorFilter();
0050 }
0051
0052 double theRDecLenCut = p.getParameter<double>("RDecLenCut") * CLHEP::cm;
0053 theDecRCut2 = theRDecLenCut * theRDecLenCut;
0054
0055 theMinPtCut2 = theMinPCut * theMinPCut;
0056
0057 double theDecLenCut = p.getParameter<double>("LDecLenCut") * CLHEP::cm;
0058
0059 maxZCentralCMS = p.getParameter<double>("MaxZCentralCMS") * CLHEP::m;
0060
0061 fFiductialCuts = (fPCuts || fPtransCut || fEtaCuts || fPhiCuts);
0062
0063 pdgFilter.resize(0);
0064 if (p.exists("PDGselection")) {
0065 pdgFilterSel = (p.getParameter<edm::ParameterSet>("PDGselection")).getParameter<bool>("PDGfilterSel");
0066 pdgFilter = (p.getParameter<edm::ParameterSet>("PDGselection")).getParameter<std::vector<int>>("PDGfilter");
0067 if (!pdgFilter.empty()) {
0068 fPDGFilter = true;
0069 std::stringstream ss;
0070 ss << "SimG4Core/Generator3: ";
0071 if (pdgFilterSel) {
0072 ss << " Selecting only PDG ID = ";
0073 } else {
0074 ss << " Filtering out PDG ID = ";
0075 }
0076 for (unsigned int ii = 0; ii < pdgFilter.size(); ++ii) {
0077 ss << pdgFilter[ii] << " ";
0078 }
0079 edm::LogVerbatim("SimG4CoreGenerator3") << ss.str();
0080 }
0081 }
0082
0083 if (fEtaCuts) {
0084 Z_lmax = theRDecLenCut * ((1 - exp(-2 * theMaxEtaCut)) / (2 * exp(-theMaxEtaCut)));
0085 Z_lmin = theRDecLenCut * ((1 - exp(-2 * theMinEtaCut)) / (2 * exp(-theMinEtaCut)));
0086 }
0087
0088 Z_hector = theRDecLenCut * ((1 - exp(-2 * theEtaCutForHector)) / (2 * exp(-theEtaCutForHector)));
0089
0090 edm::LogVerbatim("SimG4CoreGenerator3")
0091 << "SimG4Core/Generator3: Rdecaycut= " << theRDecLenCut / CLHEP::cm
0092 << " cm; Zdecaycut= " << theDecLenCut / CLHEP::cm << "Z_min= " << Z_lmin / CLHEP::cm
0093 << " cm; Z_max= " << Z_lmax / CLHEP::cm << " cm;\n"
0094 << " MaxZCentralCMS = " << maxZCentralCMS / CLHEP::m << " m;"
0095 << " Z_hector = " << Z_hector / CLHEP::cm << " cm\n"
0096 << " ApplyCuts: " << fFiductialCuts << " PCuts: " << fPCuts << " PtransCut: " << fPtransCut
0097 << " EtaCut: " << fEtaCuts << " PhiCut: " << fPhiCuts << " LumiMonitorCut: " << lumi;
0098 if (fFiductialCuts) {
0099 edm::LogVerbatim("SimG4CoreGenerator3")
0100 << "SimG4Core/Generator3: Pmin(GeV)= " << theMinPCut << "; Pmax(GeV)= " << theMaxPCut
0101 << "; EtaMin= " << theMinEtaCut << "; EtaMax= " << theMaxEtaCut << "; PhiMin(rad)= " << theMinPhiCut
0102 << "; PhiMax(rad)= " << theMaxPhiCut;
0103 }
0104 if (lumi) {
0105 fLumiFilter->Describe();
0106 }
0107 }
0108
0109 Generator3::~Generator3() { delete fLumiFilter; }
0110
0111 void Generator3::HepMC2G4(const HepMC3::GenEvent *evt_orig, G4Event *g4evt) {
0112 HepMC3::GenEvent *evt = new HepMC3::GenEvent(*evt_orig);
0113
0114
0115 if ((evt->vertices()).empty()) {
0116 std::stringstream ss;
0117 ss << "SimG4Core/Generator3: in event " << g4evt->GetEventID() << " Corrupted Event - GenEvent with no vertex \n";
0118 throw SimG4Exception(ss.str());
0119 }
0120
0121 if (!evt->weights().empty()) {
0122 weight_ = evt->weights()[0];
0123 for (unsigned int iw = 1; iw < evt->weights().size(); ++iw) {
0124
0125 if (evt->weights()[iw] <= 0)
0126 break;
0127 weight_ *= evt->weights()[iw];
0128 }
0129 }
0130
0131 if (vtx_ != nullptr) {
0132 delete vtx_;
0133 }
0134
0135 for (HepMC3::GenVertexPtr v : evt->vertices()) {
0136 vtx_ =
0137 new math::XYZTLorentzVector((v->position()).x(), (v->position()).y(), (v->position()).z(), (v->position()).t());
0138 break;
0139 }
0140
0141 edm::LogVerbatim("SimG4CoreGenerator3")
0142 << "Generator3: primary Vertex = (" << vtx_->x() << ", " << vtx_->y() << ", " << vtx_->z() << ")";
0143
0144 unsigned int ng4vtx = 0;
0145 unsigned int ng4par = 0;
0146
0147 for (HepMC3::GenVertexPtr vitr : evt->vertices()) {
0148
0149
0150
0151
0152 G4bool qvtx = false;
0153 for (HepMC3::GenParticlePtr pitr : vitr->particles_out()) {
0154
0155
0156
0157
0158 int status = pitr->status();
0159 int pdg = pitr->pid();
0160 if (status > 3 && isExotic(pdg) && (!(isExoticNonDetectable(pdg)))) {
0161
0162
0163
0164
0165
0166 status = 2;
0167 }
0168 if (status == 2 && abs(pdg) == 9900015) {
0169 status = 3;
0170 }
0171
0172
0173 if (status == 1) {
0174
0175 if (fPDGFilter && !pdgFilterSel && IsInTheFilterList(pdg)) {
0176 continue;
0177 }
0178
0179 qvtx = true;
0180 if (verbose > 2)
0181 LogDebug("SimG4CoreGenerator3")
0182 << "GenVertex barcode = " << vitr->id() << " " << qvtx
0183 << " selected for GenParticle barcode = " << pitr->id();
0184 break;
0185 }
0186
0187
0188
0189 else if (status == 2) {
0190 if (pitr->end_vertex() != nullptr) {
0191 double xx = (pitr->end_vertex())->position().x();
0192 double yy = (pitr->end_vertex())->position().y();
0193 double r_dd = xx * xx + yy * yy;
0194 if (r_dd > theDecRCut2) {
0195 qvtx = true;
0196 if (verbose > 2)
0197 LogDebug("SimG4CoreGenerator3")
0198 << "GenVertex barcode = " << vitr->id() << " selected for GenParticle barcode = " << pitr->id()
0199 << " radius = " << std::sqrt(r_dd);
0200 break;
0201 }
0202 } else {
0203
0204
0205 qvtx = true;
0206 break;
0207 }
0208 }
0209 }
0210
0211
0212
0213 if (!qvtx) {
0214 continue;
0215 }
0216
0217 double x1 = vitr->position().x() * CLHEP::mm;
0218 double y1 = vitr->position().y() * CLHEP::mm;
0219 double z1 = vitr->position().z() * CLHEP::mm;
0220 double t1 = vitr->position().t() * CLHEP::mm / CLHEP::c_light;
0221
0222 G4PrimaryVertex *g4vtx = new G4PrimaryVertex(x1, y1, z1, t1);
0223
0224 for (HepMC3::GenParticlePtr pitr : vitr->particles_out()) {
0225 int status = pitr->status();
0226 int pdg = pitr->pid();
0227 bool hasDecayVertex = (nullptr != pitr->end_vertex());
0228
0229
0230 if (fPDGFilter) {
0231 bool isInTheList = IsInTheFilterList(pdg);
0232 if ((!pdgFilterSel && isInTheList) || (pdgFilterSel && !isInTheList)) {
0233 if (0 < verbose)
0234 edm::LogVerbatim("SimG4CoreGenerator3")
0235 << " Skiped GenParticle barcode= " << pitr->id() << " PDGid= " << pdg << " status= " << status
0236 << " isExotic: " << isExotic(pdg) << " isExoticNotDet: " << isExoticNonDetectable(pdg)
0237 << " isInTheList: " << isInTheList << " hasDecayVertex: " << hasDecayVertex;
0238 continue;
0239 }
0240 }
0241
0242 if (0 < verbose) {
0243 edm::LogVerbatim("SimG4CoreGenerator3")
0244 << "Generator3: pdg= " << pdg << " status= " << status << " hasPreDefinedDecay: " << hasDecayVertex
0245 << "\n isExotic: " << isExotic(pdg) << " isExoticNotDet: " << isExoticNonDetectable(pdg)
0246 << " isInTheList: " << IsInTheFilterList(pdg) << "\n"
0247 << " MaxZCentralCMS = " << maxZCentralCMS / CLHEP::m << " m; (x,y,z,t): (" << x1 << "," << y1 << "," << z1
0248 << "," << t1 << ")";
0249 }
0250 if (status > 3 && isExotic(pdg) && (!(isExoticNonDetectable(pdg)))) {
0251 status = hasDecayVertex ? 2 : 1;
0252 }
0253 if (status == 2 && abs(pdg) == 9900015) {
0254 status = 3;
0255 }
0256
0257
0258 if (2 == status && !hasDecayVertex) {
0259 edm::LogWarning("SimG4CoreGenerator3: in event ")
0260 << g4evt->GetEventID() << " a particle "
0261 << " pdgid= " << pdg << " has status=2 but has no decay vertex, so will be fully tracked by Geant4";
0262 status = 1;
0263 }
0264
0265 double x2 = x1;
0266 double y2 = y1;
0267 double z2 = z1;
0268 double decay_length = 0.0;
0269 if (2 == status) {
0270 x2 = pitr->end_vertex()->position().x();
0271 y2 = pitr->end_vertex()->position().y();
0272 z2 = pitr->end_vertex()->position().z();
0273 decay_length = std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1));
0274 }
0275
0276 bool toBeAdded = !fFiductialCuts;
0277
0278 double px = pitr->momentum().px();
0279 double py = pitr->momentum().py();
0280 double pz = pitr->momentum().pz();
0281 double ptot = std::sqrt(px * px + py * py + pz * pz);
0282 math::XYZTLorentzVector p(px, py, pz, pitr->momentum().e());
0283
0284 double ximpact = x1;
0285 double yimpact = y1;
0286 double zimpact = z1;
0287
0288
0289
0290 const double minTan = 1.e-20;
0291 if (std::abs(z1) < Z_hector && std::abs(pz) >= minTan * ptot) {
0292 zimpact = (pz > 0.0) ? Z_hector : -Z_hector;
0293 double del = (zimpact - z1) / pz;
0294 ximpact += del * px;
0295 yimpact += del * py;
0296 }
0297 double rimpact2 = ximpact * ximpact + yimpact * yimpact;
0298
0299 if (verbose > 2)
0300 LogDebug("SimG4CoreGenerator3") << "Processing GenParticle barcode= " << pitr->id() << " pdg= " << pdg
0301 << " status= " << pitr->status() << " st= " << status
0302 << " rimpact(cm)= " << std::sqrt(rimpact2) / CLHEP::cm
0303 << " zimpact(cm)= " << zimpact / CLHEP::cm << " ptot(GeV)= " << ptot
0304 << " pz(GeV)= " << pz;
0305
0306
0307
0308 if (1 == status && std::abs(zimpact) >= Z_hector && rimpact2 <= theDecRCut2) {
0309
0310 toBeAdded = (2112 == std::abs(pdg) || 22 == pdg);
0311 if (verbose > 1) {
0312 edm::LogVerbatim("SimG4CoreGenerator3")
0313 << "GenParticle barcode = " << pitr->id() << " very forward; to be added: " << toBeAdded;
0314 }
0315 } else {
0316
0317 if (1 == status && (std::abs(zimpact) < Z_hector || rimpact2 > theDecRCut2)) {
0318
0319 if (fPCuts && (ptot < theMinPCut || ptot > theMaxPCut)) {
0320 continue;
0321 }
0322
0323 if (fPhiCuts) {
0324 double phi = p.phi();
0325 if (phi < theMinPhiCut || phi > theMaxPhiCut) {
0326 continue;
0327 }
0328 }
0329
0330
0331 if (fEtaCuts) {
0332
0333 double xi = x1;
0334 double yi = y1;
0335 double zi = z1;
0336
0337
0338 if (std::abs(pz) >= minTan * ptot) {
0339 if ((zi >= Z_lmax) & (pz < 0.0)) {
0340 zi = Z_lmax;
0341 } else if ((zi <= Z_lmin) & (pz > 0.0)) {
0342 zi = Z_lmin;
0343 } else {
0344 if (pz > 0) {
0345 zi = Z_lmax;
0346 } else {
0347 zi = Z_lmin;
0348 }
0349 }
0350 double del = (zi - z1) / pz;
0351 xi += del * px;
0352 yi += del * py;
0353 }
0354
0355 if ((zi >= Z_lmin) & (zi <= Z_lmax) & (xi * xi + yi * yi < theDecRCut2)) {
0356 continue;
0357 }
0358 }
0359 const HepMC3::GenParticle *ppointer = pitr.get();
0360 if (fLumiFilter && !fLumiFilter->isGoodForLumiMonitor(ppointer)) {
0361 continue;
0362 }
0363 toBeAdded = true;
0364 if (verbose > 1)
0365 edm::LogVerbatim("SimG4CoreGenerator3") << "GenParticle barcode = " << pitr->id() << " passed case 1";
0366
0367
0368
0369
0370 } else if (2 == status && x2 * x2 + y2 * y2 >= theDecRCut2 && std::abs(z2) < Z_hector) {
0371 toBeAdded = true;
0372 if (verbose > 1)
0373 edm::LogVerbatim("SimG4CoreGenerator3") << "GenParticle barcode = " << pitr->id() << " passed case 2"
0374 << " decay_length(cm)= " << decay_length / CLHEP::cm;
0375 }
0376 }
0377 if (toBeAdded) {
0378 G4PrimaryParticle *g4prim = new G4PrimaryParticle(pdg, px * CLHEP::GeV, py * CLHEP::GeV, pz * CLHEP::GeV);
0379
0380 if (g4prim->GetG4code() != nullptr) {
0381 g4prim->SetMass(g4prim->GetG4code()->GetPDGMass());
0382 double charge = g4prim->GetG4code()->GetPDGCharge();
0383
0384
0385 if (fPtransCut && 1 == status && 0.0 != charge && px * px + py * py < theMinPtCut2) {
0386 delete g4prim;
0387 continue;
0388 }
0389 g4prim->SetCharge(charge);
0390 }
0391
0392
0393
0394
0395 setGenId(g4prim, pitr->id());
0396
0397 if (2 == status) {
0398 particleAssignDaughters(g4prim, pitr.get(), decay_length);
0399 }
0400 if (verbose > 1)
0401 g4prim->Print();
0402
0403 ++ng4par;
0404 g4vtx->SetPrimary(g4prim);
0405 edm::LogVerbatim("SimG4CoreGenerator3") << " " << ng4par << ". new Geant4 particle pdg= " << pdg
0406 << " Ptot(GeV/c)= " << ptot << " Pt= " << std::sqrt(px * px + py * py)
0407 << " status= " << status << "; dir= " << g4prim->GetMomentumDirection();
0408 }
0409 }
0410
0411 if (verbose > 1)
0412 g4vtx->Print();
0413 g4evt->AddPrimaryVertex(g4vtx);
0414 ++ng4vtx;
0415 }
0416
0417
0418
0419 if (ng4vtx == 0) {
0420 G4PrimaryVertex *g4vtx = new G4PrimaryVertex(0.0, 0.0, 0.0, 0.0);
0421 if (verbose > 1)
0422 g4vtx->Print();
0423
0424 g4evt->AddPrimaryVertex(g4vtx);
0425 }
0426
0427 edm::LogVerbatim("SimG4CoreGenerator3")
0428 << "The list of Geant4 primaries includes " << ng4par << " particles in " << ng4vtx << " vertex";
0429
0430 delete evt;
0431 }
0432
0433 void Generator3::particleAssignDaughters(G4PrimaryParticle *g4p, HepMC3::GenParticle *vp, double decaylength) {
0434 if (verbose > 1) {
0435 LogDebug("SimG4CoreGenerator3") << "Special case of long decay length \n"
0436 << "Assign daughters to mother with decaylength=" << decaylength / CLHEP::cm
0437 << " cm";
0438 }
0439 math::XYZTLorentzVector p(vp->momentum().px(), vp->momentum().py(), vp->momentum().pz(), vp->momentum().e());
0440
0441
0442 double proper_time = decaylength / (p.Beta() * p.Gamma() * c_light);
0443 g4p->SetProperTime(proper_time);
0444
0445 if (verbose > 2) {
0446 LogDebug("SimG4CoreGenerator3") << " px= " << p.px() << " py= " << p.py() << " pz= " << p.pz() << " e= " << p.e()
0447 << " beta= " << p.Beta() << " gamma= " << p.Gamma()
0448 << " Proper time= " << proper_time / CLHEP::ns << " ns";
0449 }
0450
0451
0452
0453 double x1 = vp->end_vertex()->position().x();
0454 double y1 = vp->end_vertex()->position().y();
0455 double z1 = vp->end_vertex()->position().z();
0456
0457 for (HepMC3::GenParticlePtr vpdec : vp->end_vertex()->particles_out()) {
0458
0459 math::XYZTLorentzVector pdec(
0460 vpdec->momentum().px(), vpdec->momentum().py(), vpdec->momentum().pz(), vpdec->momentum().e());
0461
0462
0463 G4PrimaryParticle *g4daught =
0464 new G4PrimaryParticle(vpdec->pid(), pdec.x() * CLHEP::GeV, pdec.y() * CLHEP::GeV, pdec.z() * CLHEP::GeV);
0465
0466 if (g4daught->GetG4code() != nullptr) {
0467 g4daught->SetMass(g4daught->GetG4code()->GetPDGMass());
0468 g4daught->SetCharge(g4daught->GetG4code()->GetPDGCharge());
0469 }
0470
0471
0472
0473 setGenId(g4daught, vpdec->id());
0474
0475 int status = vpdec->status();
0476 if (verbose > 1)
0477 LogDebug("SimG4CoreGenerator3::::particleAssignDaughters")
0478 << "Assigning a " << vpdec->pid() << " as daughter of a " << vp->pid() << " status=" << status;
0479
0480 if ((status == 2 || (status == 23 && std::abs(vp->pid()) == 1000015) || (status > 50 && status < 100)) &&
0481 vpdec->end_vertex() != nullptr) {
0482 double x2 = vpdec->end_vertex()->position().x();
0483 double y2 = vpdec->end_vertex()->position().y();
0484 double z2 = vpdec->end_vertex()->position().z();
0485 double dd = std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
0486 particleAssignDaughters(g4daught, vpdec.get(), dd);
0487 }
0488 vpdec->set_status(1000 + status);
0489 g4p->SetDaughter(g4daught);
0490
0491 if (verbose > 1)
0492 g4daught->Print();
0493 }
0494 }
0495
0496
0497 bool Generator3::particlePassesPrimaryCuts(const G4ThreeVector &p) const {
0498 bool flag = true;
0499 double ptot = p.mag();
0500 if (fPCuts && (ptot < theMinPCut * CLHEP::GeV || ptot > theMaxPCut * CLHEP::GeV)) {
0501 flag = false;
0502 }
0503 if (fEtaCuts && flag) {
0504 double pz = p.z();
0505 if (ptot < pz + 1.e-10) {
0506 flag = false;
0507
0508 } else {
0509 double eta = 0.5 * G4Log((ptot + pz) / (ptot - pz));
0510 if (eta < theMinEtaCut || eta > theMaxEtaCut) {
0511 flag = false;
0512 }
0513 }
0514 }
0515 if (fPhiCuts && flag) {
0516 double phi = p.phi();
0517 if (phi < theMinPhiCut || phi > theMaxPhiCut) {
0518 flag = false;
0519 }
0520 }
0521
0522 if (verbose > 2)
0523 LogDebug("SimG4CoreGenerator3") << "Generator ptot(GeV)= " << ptot / CLHEP::GeV << " eta= " << p.eta()
0524 << " phi= " << p.phi() << " Flag= " << flag;
0525
0526 return flag;
0527 }
0528
0529 bool Generator3::isExotic(int pdgcode) const {
0530 int pdgid = std::abs(pdgcode);
0531 return ((pdgid >= 1000000 && pdgid < 4000000 && pdgid != 3000022) ||
0532 pdgid == 17 ||
0533 pdgid == 34 ||
0534 pdgid == 37);
0535 }
0536
0537 bool Generator3::isExoticNonDetectable(int pdgcode) const {
0538 int pdgid = std::abs(pdgcode);
0539 HepPDT::ParticleID pid(pdgcode);
0540 int charge = pid.threeCharge();
0541 return ((charge == 0) && (pdgid >= 1000000 && pdgid < 1000040));
0542 }
0543
0544 bool Generator3::IsInTheFilterList(int pdgcode) const {
0545 int pdgid = std::abs(pdgcode);
0546 for (auto &pdg : pdgFilter) {
0547 if (std::abs(pdg) == pdgid) {
0548 return true;
0549 }
0550 }
0551 return false;
0552 }
0553
0554 void Generator3::nonCentralEvent2G4(const HepMC3::GenEvent *evt, G4Event *g4evt) {
0555 #if 0
0556
0557 int i = g4evt->GetNumberOfPrimaryVertex();
0558 for (HepMC3::GenEvent::particle_const_iterator it = evt->particles_begin(); it != evt->particles_end(); ++it) {
0559 ++i;
0560 HepMC3::GenParticle *gp = (*it);
0561
0562
0563 if (gp->status() != 1)
0564 continue;
0565
0566 int pdg = gp->pdg_id();
0567 G4PrimaryParticle *g4p = new G4PrimaryParticle(
0568 pdg, gp->momentum().px() * CLHEP::GeV, gp->momentum().py() * CLHEP::GeV, gp->momentum().pz() * CLHEP::GeV);
0569 if (g4p->GetG4code() != nullptr) {
0570 g4p->SetMass(g4p->GetG4code()->GetPDGMass());
0571 g4p->SetCharge(g4p->GetG4code()->GetPDGCharge());
0572 }
0573 setGenId(g4p, i);
0574 G4PrimaryVertex *v = new G4PrimaryVertex(gp->production_vertex()->position().x() * CLHEP::mm,
0575 gp->production_vertex()->position().y() * CLHEP::mm,
0576 gp->production_vertex()->position().z() * CLHEP::mm,
0577 gp->production_vertex()->position().t() * CLHEP::mm / CLHEP::c_light);
0578 v->SetPrimary(g4p);
0579 g4evt->AddPrimaryVertex(v);
0580 if (verbose > 0)
0581 v->Print();
0582 }
0583
0584 #endif
0585 }