Import Geant4 10.7.0 source tree
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "PrimaryGeneratorAction.hh"
|
||||
#include "PrimaryGeneratorMessenger.hh"
|
||||
|
||||
#include "G4Box.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4LogicalVolumeStore.hh"
|
||||
#include "G4ParticleGun.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4RunManager.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
#ifdef WITHROOT
|
||||
#include "G4MTRunManager.hh"
|
||||
#include "G4Run.hh"
|
||||
#include "TFile.h"
|
||||
#include "TTreeReader.h"
|
||||
#include "TTreeReaderValue.h"
|
||||
#endif
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
PrimaryGeneratorAction::PrimaryGeneratorAction()
|
||||
: G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr),
|
||||
fEnvelopeBox(nullptr) {
|
||||
G4int n_particle = 1;
|
||||
fParticleGun = new G4ParticleGun(n_particle);
|
||||
|
||||
// default particle kinematic
|
||||
G4ParticleTable *particleTable = G4ParticleTable::GetParticleTable();
|
||||
G4String particleName;
|
||||
G4ParticleDefinition *particle =
|
||||
particleTable->FindParticle(particleName = "e+");
|
||||
fParticleGun->SetParticleDefinition(particle);
|
||||
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
|
||||
fParticleGun->SetParticleEnergy(30. * CLHEP::GeV);
|
||||
fParticleGun->SetParticlePosition(G4ThreeVector(0., 0., 0.));
|
||||
|
||||
fMessenger = new PrimaryGeneratorMessenger(this);
|
||||
#ifdef WITHROOT
|
||||
if (fReadInputFile)
|
||||
OpenInput();
|
||||
#endif
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#ifdef WITHROOT
|
||||
void PrimaryGeneratorAction::OpenInput() {
|
||||
if (fInputFile != nullptr) {
|
||||
delete fInputFile;
|
||||
fInputFile = nullptr;
|
||||
}
|
||||
fInputFile = new TFile(fPathInputFile, "READ");
|
||||
if (fInputFile == nullptr || fInputFile->IsZombie()) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Input file '" << fPathInputFile << "' cannot be opened.\n";
|
||||
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()", "WrongInputName",
|
||||
FatalErrorInArgument, msg);
|
||||
}
|
||||
auto fileDirectory =
|
||||
dynamic_cast<TDirectory *>(fInputFile->Get("VirtualDetector"));
|
||||
if (fileDirectory == nullptr) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Input file '" << fPathInputFile
|
||||
<< "' does not contain 'VirtualDetector' directory.\n";
|
||||
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
|
||||
"WrongInputDirectory", FatalErrorInArgument, msg);
|
||||
}
|
||||
fHgcalReader = new TTreeReader("HGCAL", fileDirectory);
|
||||
fHgcalEventId = new TTreeReaderValue<Float_t>(*fHgcalReader, "EventID");
|
||||
fHgcalPdgId = new TTreeReaderValue<Float_t>(*fHgcalReader, "PDGid");
|
||||
fHgcalPosX = new TTreeReaderValue<Float_t>(*fHgcalReader, "x");
|
||||
fHgcalPosY = new TTreeReaderValue<Float_t>(*fHgcalReader, "y");
|
||||
fHgcalMomX = new TTreeReaderValue<Float_t>(*fHgcalReader, "Px");
|
||||
fHgcalMomY = new TTreeReaderValue<Float_t>(*fHgcalReader, "Py");
|
||||
fHgcalMomZ = new TTreeReaderValue<Float_t>(*fHgcalReader, "Pz");
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
PrimaryGeneratorAction::~PrimaryGeneratorAction() {
|
||||
delete fParticleGun;
|
||||
#ifdef WITHROOT
|
||||
delete fInputFile;
|
||||
#endif
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void PrimaryGeneratorAction::GeneratePrimaries(G4Event *anEvent) {
|
||||
#ifdef WITHROOT
|
||||
if (fReadInputFile) {
|
||||
// get primary particles from input file
|
||||
if (fInputFile == nullptr) {
|
||||
OpenInput();
|
||||
}
|
||||
Float_t currentEventId = -1;
|
||||
while (fHgcalReader->Next()) {
|
||||
// First particle - set event ID
|
||||
if (currentEventId == -1) {
|
||||
currentEventId = **fHgcalEventId;
|
||||
fEventCounter++;
|
||||
// check if event should be ignored (is before the start position)
|
||||
if (fEventCounter < fStartFromEvent)
|
||||
continue;
|
||||
} else {
|
||||
// check if event is to be skipped
|
||||
if (fEventCounter < fStartFromEvent) {
|
||||
if (currentEventId != **fHgcalEventId)
|
||||
currentEventId = -1;
|
||||
continue;
|
||||
} else {
|
||||
// check if current particle belongs to the next event
|
||||
if (currentEventId != **fHgcalEventId)
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto vertex = new G4PrimaryVertex(
|
||||
G4ThreeVector(**fHgcalPosX, **fHgcalPosY, 32.5 * CLHEP::mm), 0 * CLHEP::s);
|
||||
auto particleDefinition =
|
||||
G4ParticleTable::GetParticleTable()->FindParticle(**fHgcalPdgId);
|
||||
auto particle = new G4PrimaryParticle(particleDefinition);
|
||||
G4ThreeVector momentum(**fHgcalMomX, **fHgcalMomY, **fHgcalMomZ);
|
||||
particle->SetMomentumDirection(momentum.unit());
|
||||
particle->SetKineticEnergy(momentum.mag());
|
||||
vertex->SetPrimary(particle);
|
||||
anEvent->AddPrimaryVertex(vertex);
|
||||
}
|
||||
// if no particles are left - terminate run
|
||||
if (fEventCounter >= fStartFromEvent &&
|
||||
anEvent->GetNumberOfPrimaryVertex() == 0) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Input file does not contain any more events (current event ID = "
|
||||
<< anEvent->GetEventID() << ").\n";
|
||||
msg << "Run will be aborted with " << anEvent->GetEventID()
|
||||
<< " events processed.\n";
|
||||
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
|
||||
"EndOfInputFile", JustWarning, msg);
|
||||
G4RunManager::GetRunManager()->AbortRun();
|
||||
}
|
||||
// warn if this is the last event and some events are left in the file
|
||||
// unprocessed
|
||||
if (G4RunManager::GetRunManager()
|
||||
->GetCurrentRun()
|
||||
->GetNumberOfEventToBeProcessed() == anEvent->GetEventID() + 1) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Input file contains more events than requested in the run.\n";
|
||||
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
|
||||
"UnusedEventsInInputFile", JustWarning, msg);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Beam position: z
|
||||
// Use value set by UI command, or set it to edge of the world volume
|
||||
if (fBeamZ0 == -999 * CLHEP::m) {
|
||||
G4double worldDZ = 0;
|
||||
if (!fEnvelopeBox) {
|
||||
G4LogicalVolume *envLV =
|
||||
G4LogicalVolumeStore::GetInstance()->GetVolume("World");
|
||||
if (envLV)
|
||||
fEnvelopeBox = dynamic_cast<G4Box *>(envLV->GetSolid());
|
||||
}
|
||||
if (fEnvelopeBox) {
|
||||
worldDZ = fEnvelopeBox->GetZHalfLength();
|
||||
fBeamZ0 = -worldDZ;
|
||||
} else {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "World volume of box shape not found.\n";
|
||||
msg << "Perhaps you have changed geometry.\n";
|
||||
msg << "The gun will be place at the center.";
|
||||
G4Exception("PrimaryGeneratorAction::GeneratePrimaries()",
|
||||
"WorldVolume", JustWarning, msg);
|
||||
}
|
||||
}
|
||||
// Beam position: x,y
|
||||
switch (fBeamType) {
|
||||
case eNone:
|
||||
default:
|
||||
fParticleGun->SetParticlePosition(G4ThreeVector(0, 0, fBeamZ0));
|
||||
break;
|
||||
case eGaussian:
|
||||
fParticleGun->SetParticlePosition(
|
||||
G4ThreeVector(G4RandGauss::shoot(0., fSigmaBeamX),
|
||||
G4RandGauss::shoot(0., fSigmaBeamY), fBeamZ0));
|
||||
break;
|
||||
case eFlat:
|
||||
fParticleGun->SetParticlePosition(
|
||||
G4ThreeVector(G4RandFlat::shoot(-fSigmaBeamX, fSigmaBeamX),
|
||||
G4RandFlat::shoot(-fSigmaBeamY, fSigmaBeamY), fBeamZ0));
|
||||
break;
|
||||
}
|
||||
// Particle momentum
|
||||
if (fMomentumGaussianSpread > 0) {
|
||||
double energy = fParticleGun->GetParticleEnergy();
|
||||
energy += G4RandGauss::shoot(0., fMomentumGaussianSpread) * energy;
|
||||
fParticleGun->SetParticleEnergy(energy);
|
||||
}
|
||||
fParticleGun->GeneratePrimaryVertex(anEvent);
|
||||
}
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
Reference in New Issue
Block a user