add detector simulation
This commit is contained in:
@@ -1,28 +1,3 @@
|
||||
/*//////////////////////////////////////////////////////////////////////////////
|
||||
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
||||
All rights reserved
|
||||
|
||||
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
|
||||
|
||||
------------------------------------------------------------------
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#include <Geant4/G4Box.hh>
|
||||
#include <Geant4/G4LogicalVolume.hh>
|
||||
#include <Geant4/G4Material.hh>
|
||||
@@ -42,13 +17,15 @@
|
||||
#include "Scene.h"
|
||||
#include "PhysicsList.hh"
|
||||
#include "ActionInitialization.hh"
|
||||
#include "SimulationContext.h"
|
||||
#include "HEP/Detectors/DetectorChamber.h"
|
||||
|
||||
namespace uLib {
|
||||
namespace Geant {
|
||||
|
||||
class SceneDetectorConstruction : public DetectorConstruction {
|
||||
public:
|
||||
SceneDetectorConstruction(class SceneImpl *owner);
|
||||
SceneDetectorConstruction(class SceneImpl *owner) : DetectorConstruction("Scene"), m_Owner(owner) {}
|
||||
G4VPhysicalVolume *Construct() override;
|
||||
private:
|
||||
class SceneImpl *m_Owner;
|
||||
@@ -69,57 +46,50 @@ static void CheckGeant4Environment() {
|
||||
|
||||
class SceneImpl {
|
||||
public:
|
||||
// constructor //
|
||||
SceneImpl() : m_RunManager(G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default)),
|
||||
m_Emitter(nullptr),
|
||||
m_Output(nullptr),
|
||||
m_Verbosity(0) {
|
||||
m_InitCalled(false) {
|
||||
m_RunManager->SetUserInitialization(new PhysicsList);
|
||||
}
|
||||
|
||||
// destructor //
|
||||
~SceneImpl() {
|
||||
if (m_RunManager) delete m_RunManager;
|
||||
if (m_World) delete m_World;
|
||||
// m_World deletion is handled in Scene destructor or here
|
||||
}
|
||||
|
||||
void Initialize() {
|
||||
// Set mandatory initialization classes for Geant4
|
||||
m_RunManager->SetUserInitialization(new SceneDetectorConstruction(this));
|
||||
m_RunManager->SetUserInitialization(
|
||||
new ActionInitialization(m_Emitter, m_Output, m_Verbosity));
|
||||
if (m_InitCalled) return;
|
||||
|
||||
m_RunManager->SetUserInitialization(new SceneDetectorConstruction(this));
|
||||
m_RunManager->SetUserInitialization(new ActionInitialization(m_Emitter, &m_Context));
|
||||
|
||||
m_RunManager->SetVerboseLevel(m_Verbosity);
|
||||
|
||||
// Initialize Geant4
|
||||
m_RunManager->Initialize();
|
||||
m_InitCalled = true;
|
||||
}
|
||||
|
||||
// members //
|
||||
Vector<Solid *> m_Solids;
|
||||
Solid *m_World = nullptr;
|
||||
ContainerBox m_WorldBox;
|
||||
G4RunManager *m_RunManager;
|
||||
EmitterPrimary *m_Emitter;
|
||||
Vector<GeantEvent> *m_Output;
|
||||
int m_Verbosity;
|
||||
SimulationContext m_Context;
|
||||
bool m_InitCalled;
|
||||
};
|
||||
|
||||
SceneDetectorConstruction::SceneDetectorConstruction(SceneImpl *owner)
|
||||
: DetectorConstruction("Scene"), m_Owner(owner) {}
|
||||
|
||||
G4VPhysicalVolume *SceneDetectorConstruction::Construct() {
|
||||
return m_Owner->m_World->GetPhysical();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Scene::Scene() {
|
||||
CheckGeant4Environment();
|
||||
d = new SceneImpl();
|
||||
}
|
||||
Scene::~Scene() { delete d; }
|
||||
|
||||
Scene::~Scene() {
|
||||
// Delete solids
|
||||
for(auto s : d->m_Solids) delete s;
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Scene::AddSolid(Solid *solid, Solid *parent) {
|
||||
d->m_Solids.push_back(solid);
|
||||
@@ -131,12 +101,9 @@ void Scene::AddSolid(Solid *solid, Solid *parent) {
|
||||
}
|
||||
|
||||
const Solid* Scene::GetWorld() const { return d->m_World; }
|
||||
|
||||
ContainerBox* Scene::GetWorldBox() const { return &d->m_WorldBox; }
|
||||
|
||||
void Scene::ConstructWorldBox(const Vector3f &size, const char *material) {
|
||||
// Get nist material manager
|
||||
|
||||
d->m_WorldBox.Scale(size);
|
||||
d->m_WorldBox.SetPosition(-size/2.0f);
|
||||
|
||||
@@ -146,61 +113,48 @@ void Scene::ConstructWorldBox(const Vector3f &size, const char *material) {
|
||||
AddSolid(d->m_World);
|
||||
}
|
||||
|
||||
G4Box *solidWorld = new G4Box("World",
|
||||
0.5 * size(0),
|
||||
0.5 * size(1),
|
||||
0.5 * size(2));
|
||||
|
||||
G4LogicalVolume *logicWorld = new G4LogicalVolume(solidWorld,
|
||||
d->m_World->GetMaterial(),
|
||||
d->m_World->GetName());
|
||||
|
||||
G4Box *solidWorld = new G4Box("World", 0.5 * size(0), 0.5 * size(1), 0.5 * size(2));
|
||||
G4LogicalVolume *logicWorld = new G4LogicalVolume(solidWorld, d->m_World->GetMaterial(), d->m_World->GetName());
|
||||
d->m_World->SetLogical(logicWorld);
|
||||
|
||||
G4PVPlacement *physWorld = new G4PVPlacement(
|
||||
nullptr,
|
||||
G4ThreeVector(0, 0, 0),
|
||||
logicWorld,
|
||||
d->m_World->GetName(),
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
true);
|
||||
|
||||
G4PVPlacement *physWorld = new G4PVPlacement(nullptr, G4ThreeVector(0, 0, 0), logicWorld, d->m_World->GetName(), 0, false, 0, true);
|
||||
d->m_World->SetPhysical(physWorld);
|
||||
|
||||
// no transforms are allowed for the world box
|
||||
// Matrix4f transform = box->GetMatrix();
|
||||
// d->m_World->SetTransform(transform);
|
||||
}
|
||||
|
||||
void Scene::SetEmitter(EmitterPrimary *emitter) {
|
||||
d->m_Emitter = emitter;
|
||||
}
|
||||
|
||||
void Scene::Initialize() {
|
||||
d->Initialize();
|
||||
}
|
||||
void Scene::SetEmitter(EmitterPrimary *emitter) { d->m_Emitter = emitter; }
|
||||
void Scene::Initialize() { d->Initialize(); }
|
||||
void Scene::SetVerbosity(int level) {
|
||||
d->m_Verbosity = level;
|
||||
d->m_Context.verbosity = level;
|
||||
if (d->m_RunManager) d->m_RunManager->SetVerboseLevel(level);
|
||||
}
|
||||
|
||||
void Scene::RunSimulation(int nEvents, Vector<GeantEvent> &results) {
|
||||
d->m_Output = &results;
|
||||
d->Initialize(); // Ensure initialized
|
||||
d->m_Context.mode = SimulationMode::DETAILED;
|
||||
d->m_Context.outputGeant = &results;
|
||||
d->m_Context.outputMuon = nullptr;
|
||||
|
||||
d->m_RunManager->BeamOn(nEvents);
|
||||
}
|
||||
|
||||
// Re-initialize ActionInitialization with the output buffer
|
||||
// (ActionInitialization was already set during Initialize, but we need
|
||||
// to ensure the output pointer is current)
|
||||
d->m_RunManager->SetUserInitialization(
|
||||
new ActionInitialization(d->m_Emitter, &results, d->m_Verbosity));
|
||||
|
||||
// Re-run initialization to propagate the ActionInitialization change to worker threads
|
||||
d->m_RunManager->Initialize();
|
||||
void Scene::RunDetectorSimulation(int nEvents, Vector<MuonEvent> &results) {
|
||||
d->Initialize(); // Ensure initialized
|
||||
d->m_Context.mode = SimulationMode::DETECTOR;
|
||||
d->m_Context.outputGeant = nullptr;
|
||||
d->m_Context.outputMuon = &results;
|
||||
|
||||
// Find detector planes
|
||||
d->m_Context.detectorPlanes.clear();
|
||||
for (Solid* s : d->m_Solids) {
|
||||
if (BoxSolid* bs = dynamic_cast<BoxSolid*>(s)) {
|
||||
if (DetectorChamber* dc = dynamic_cast<DetectorChamber*>(bs->GetObject())) {
|
||||
d->m_Context.detectorPlanes.push_back(dc->GetWorldProjectionPlane());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d->m_RunManager->BeamOn(nEvents);
|
||||
}
|
||||
|
||||
} // namespace Geant
|
||||
} // namespace uLib
|
||||
|
||||
|
||||
Reference in New Issue
Block a user