9#include <simulation/kernel/MCParticleGenerator.h> 
   11#include <mdst/dataobjects/MCParticle.h> 
   12#include <framework/gearbox/Unit.h> 
   13#include <framework/logging/Logger.h> 
   14#include <framework/datastore/StoreArray.h> 
   15#include <simulation/kernel/UserInfo.h> 
   16#include <geometry/GeometryManager.h> 
   18#include <G4ParticleTable.hh> 
   19#include <G4VUserPrimaryParticleInformation.hh> 
   20#include <G4ParticleDefinition.hh> 
   21#include <G4ParticleTypes.hh> 
   22#include <G4VPhysicalVolume.hh> 
   23#include <G4LogicalVolume.hh> 
   25#include <CLHEP/Vector/LorentzVector.h> 
   29using namespace Belle2::Simulation;
 
   33  G4VPrimaryGenerator(), m_mcCollectionName(mcCollectionName), m_mcParticleGraph(mcParticleGraph)
 
   37    m_topSolid = topVolume->GetLogicalVolume()->GetSolid();
 
   65  for (
int iPart = 0; iPart < nPart; iPart++) {
 
   67    if (currParticle->
getMother() != NULL) 
continue;
 
   78  ROOT::Math::XYZVector mcProdVtx = p.getProductionVertex();
 
   79  G4ThreeVector pos(mcProdVtx.X() / 
Unit::mm * CLHEP::mm,
 
   80                    mcProdVtx.Y() / 
Unit::mm * CLHEP::mm,
 
   81                    mcProdVtx.Z() / 
Unit::mm * CLHEP::mm);
 
   82  productionTimeShift = 0;
 
   87    ROOT::Math::PxPyPzEVector mcPartMom4 = p.get4Vector();
 
   88    CLHEP::HepLorentzVector mom(mcPartMom4.X() / 
Unit::MeV * CLHEP::MeV,
 
   92    const auto dir = mom.vect().unit();
 
   93    double distance = 
m_topSolid->DistanceToIn(pos, dir);
 
   95    if (distance == kInfinity) {
 
   96      B2DEBUG(10, 
"Particle starts outside simulation volume and isn't intersecting, skipping");
 
  100    const double speed = (p.getMass() == 0 ? mom.beta() : 1) * CLHEP::c_light;
 
  101    const double flightLength = speed * p.getLifetime();
 
  102    if (distance > flightLength) {
 
  103      B2DEBUG(10, 
"Particle starts outside simulation volume and doesn't reach it before decaying, skipping");
 
  106    pos += dir * distance;
 
  107    productionTimeShift = (distance / speed);
 
  109  return new G4PrimaryVertex(pos.x(), pos.y(), pos.z(), p.getProductionTime() + productionTimeShift);
 
  114                                      G4PrimaryParticle* lastG4Mother,
 
  118  G4PrimaryParticle* g4Mother = lastG4Mother;
 
  129  G4ParticleDefinition* pdef = NULL;
 
  131    pdef = G4OpticalPhoton::OpticalPhotonDefinition();
 
  133    pdef = G4ParticleTable::GetParticleTable()->FindParticle(mcParticle.
getPDG());
 
  134    if (pdef == NULL && neutral_llp) {
 
  135      pdef = G4ParticleTable::GetParticleTable()->FindParticle(
"LongLivedNeutralParticle");
 
  142      B2WARNING(
"PDG code " << mcParticle.
getPDG() << 
" unknown to Geant4 - particle skipped.");
 
  165  G4PrimaryParticle* newPart = 
nullptr;
 
  167  G4PrimaryVertex* vertex = 
nullptr;
 
  170  double productionTimeShift{0};
 
  174  if (addToG4 and lastG4Mother == 
nullptr) {
 
  177    if (not vertex) addToG4 = 
false;
 
  182    const ROOT::Math::PxPyPzEVector mcPartMom4 = graphParticle.
get4Vector();
 
  183    newPart = 
new G4PrimaryParticle(pdef,
 
  187                                    mcPartMom4.E() / 
Unit::MeV * CLHEP::MeV);
 
  190      ROOT::Math::XYZVector polarization = graphParticle.
getDecayVertex(); 
 
  191      newPart->SetPolarization(polarization.X(), polarization.Y(), polarization.Z());
 
  193    newPart->SetUserInformation(
new ParticleInfo(graphParticle));
 
  200      double propertime = (graphParticle.
getLifetime() - productionTimeShift) / mcPartMom4.Gamma();
 
  201      newPart->SetProperTime(propertime);
 
  205      lastG4Mother->SetDaughter(newPart);
 
  211      vertex->SetPrimary(newPart);
 
  212      event->AddPrimaryVertex(vertex);
 
  221    B2DEBUG(100, 
"The particle " << mcParticle.
getIndex() << 
" (PDG " << mcParticle.
getPDG() << 
") was not added to Geant4");
 
  227    addParticle(*daughter, event, g4Mother, currMotherIndex, useTime);
 
Class to represent Particle data in graph.
void comesFrom(GraphParticle &mother)
Tells the graph that this particle is a decay product of mother.
void setFirstDaughter(int daughter)
Set the 1-based index of the first daughter, 0 means no daughters.
void setLastDaughter(int daughter)
Set the 1-based index of the last daughter, 0 means no daughters.
void setIgnore(bool ignore=true)
Set or remove the ignore flag.
Class to build, validate and sort a particle decay chain.
size_t size() const
Return the number of particles in the graph.
A Class to store the Monte Carlo particle information.
float getEnergy() const
Return particle energy in GeV.
void setDecayTime(float time)
Set decay time.
void setMass(float mass)
Set particle mass.
void setDecayVertex(const ROOT::Math::XYZVector &vertex)
Set decay vertex.
int getIndex() const
Get 1-based index of the particle in the corresponding MCParticle list.
ROOT::Math::XYZVector getDecayVertex() const
Return decay vertex.
float getLifetime() const
Return the lifetime in ns.
void setEnergy(float energy)
Set energy.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
float getMass() const
Return the particle mass in GeV.
ROOT::Math::XYZVector getProductionVertex() const
Return production vertex position.
float getDecayTime() const
Return the decay time in ns.
void setValidVertex(bool valid)
Set indication wether vertex and time information is valid or just default.
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
bool hasValidVertex() const
Indication whether vertex and time information is useful or just default.
unsigned int getStatus(unsigned short int bitmask=USHRT_MAX) const
Return status code of particle.
int getLastDaughter() const
Get 1-based index of last daughter, 0 if no daughters.
float getCharge() const
Return the particle charge defined in TDatabasePDG.
ROOT::Math::PxPyPzEVector get4Vector() const
Return 4Vector of particle.
void setPDG(int pdg)
Set PDG code of the particle.
int getPDG() const
Return PDG code of particle.
float getProductionTime() const
Return production time in ns.
ROOT::Math::XYZVector getMomentum() const
Return momentum.
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
void setStatus(unsigned short int status)
Set Status code for the particle.
int getFirstDaughter() const
Get 1-based index of first daughter, 0 if no daughters.
void setProductionTime(float time)
Set production time.
std::string m_mcCollectionName
Name of the MCParticle collection.
virtual ~MCParticleGenerator()
The destructor of the MCParticleGenerator class.
MCParticleGraph & m_mcParticleGraph
Reference to the MCParticle graph.
void addParticle(const MCParticle &mcParticle, G4Event *event, G4PrimaryParticle *lastG4Mother, int motherIndex, bool useTime)
Takes a MCParticle and creates a primary particle for Geant4.
virtual void GeneratePrimaryVertex(G4Event *event)
Create G4 primary particles from MCParticle list.
G4VSolid * m_topSolid
Pointer to the top level solid to check if particles are inside the simulation volume.
G4PrimaryVertex * determineVertex(const MCParticleGraph::GraphParticle &p, double &productionTimeShift)
Create a simulation vertex for the given particle.
MCParticleGenerator(const std::string &mcCollectionName, MCParticleGraph &mcParticleGraph)
The constructor of the MCParticleGenerator class.
UserInfo class which is used to attach additional information to Geant4 particles and tracks.
Accessor to arrays stored in the data store.
int getEntries() const
Get the number of objects in the array.
static const double mm
[millimeters]
static const double eV
[electronvolt]
static const double MeV
[megaelectronvolt]
G4VPhysicalVolume * getTopVolume()
Return a pointer to the top volume.
static GeometryManager & getInstance()
Return a reference to the instance.
bool isInitial() const
Check if particle is an initial particle such as ISR.
MCParticle * getMother() const
Returns a pointer to the mother particle.
void clear()
Reset particles and decay information to make the class reusable.
GraphParticle & addParticle()
Add new particle to the graph.
bool isVirtual() const
Check if particle is virtual.
Abstract base class for different kinds of events.