geant events for multiple scattering
This commit is contained in:
140
src/Vtk/HEP/Geant/testing/vtkGeantEventTest.cpp
Normal file
140
src/Vtk/HEP/Geant/testing/vtkGeantEventTest.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/*//////////////////////////////////////////////////////////////////////////////
|
||||
// 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 >
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
#include "Geant/Solid.h"
|
||||
#include "HEP/Geant/GeantEvent.h"
|
||||
#include "HEP/Geant/Scene.h"
|
||||
#include "HEP/Geant/EmitterPrimary.hh"
|
||||
#include "Math/ContainerBox.h"
|
||||
#include "Math/Dense.h"
|
||||
#include "Vtk/uLibVtkViewer.h"
|
||||
#include "Vtk/HEP/Geant/vtkGeantEvent.h"
|
||||
#include "Vtk/vtkContainerBox.h"
|
||||
|
||||
#include <vtkSmartPointer.h>
|
||||
#include <vtkCallbackCommand.h>
|
||||
#include <vtkRenderWindowInteractor.h>
|
||||
#include <vtkProperty.h>
|
||||
#include <vtkRenderer.h>
|
||||
#include <vtkRenderWindow.h>
|
||||
|
||||
#include <Geant4/Randomize.hh>
|
||||
#include <Geant4/G4ParticleGun.hh>
|
||||
#include <Geant4/G4SystemOfUnits.hh>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace uLib;
|
||||
|
||||
// Custom emitter to fire random muons towards the cube
|
||||
class RandomEmitter : public Geant::EmitterPrimary {
|
||||
public:
|
||||
virtual void GeneratePrimaries(G4Event* anEvent) override {
|
||||
// Start from a random point in a square at z = 5m
|
||||
// Note: unit in Geant4 is mm by default if not specified,
|
||||
// but here we use the constants from G4SystemOfUnits.h
|
||||
double x = (G4UniformRand() - 0.5) * 2000; // -1m to 1m
|
||||
double y = (G4UniformRand() - 0.5) * 2000; // -1m to 1m
|
||||
double z = 5000.0; // 5m above origin
|
||||
|
||||
fParticleGun->SetParticlePosition(G4ThreeVector(x, y, z));
|
||||
|
||||
// Aim at a random point within the cube (which is at origin, size 1m)
|
||||
double tx = (G4UniformRand() - 0.5) * 1000;
|
||||
double ty = (G4UniformRand() - 0.5) * 1000;
|
||||
double tz = (G4UniformRand() - 0.5) * 1000;
|
||||
|
||||
G4ThreeVector dir(tx - x, ty - y, tz - z);
|
||||
dir = dir.unit();
|
||||
fParticleGun->SetParticleMomentumDirection(dir);
|
||||
|
||||
fParticleGun->GeneratePrimaryVertex(anEvent);
|
||||
}
|
||||
};
|
||||
|
||||
struct AppState {
|
||||
Geant::Scene* scene;
|
||||
Vtk::Viewer* viewer;
|
||||
Vector<Geant::GeantEvent> results;
|
||||
};
|
||||
|
||||
void KeyPressCallbackFunction(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData) {
|
||||
auto* interactor = static_cast<vtkRenderWindowInteractor*>(caller);
|
||||
auto* state = static_cast<AppState*>(clientData);
|
||||
|
||||
std::string key = interactor->GetKeySym();
|
||||
if (key == "Return") {
|
||||
std::cout << "--> Firing random muon..." << std::endl;
|
||||
|
||||
// Run one event
|
||||
state->scene->RunSimulation(1, state->results);
|
||||
|
||||
if (!state->results.empty()) {
|
||||
// Get the last event
|
||||
Geant::GeantEvent* lastEvent = &state->results.back();
|
||||
std::cout << " Collected event " << lastEvent->GetEventID()
|
||||
<< " with " << lastEvent->Path().size() << " steps." << std::endl;
|
||||
|
||||
// Wrap it for VTK
|
||||
Vtk::vtkGeantEvent* vtkEvent = new Vtk::vtkGeantEvent(lastEvent);
|
||||
state->viewer->AddPuppet(*vtkEvent);
|
||||
|
||||
// Re-render
|
||||
state->viewer->GetRenderer()->Render();
|
||||
state->viewer->GetRenderWindow()->Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// 1. Setup Geant4 Scene
|
||||
ContainerBox world_box(Vector3f(30000, 30000, 30000));
|
||||
Geant::Scene scene;
|
||||
scene.ConstructWorldBox(&world_box, "G4_AIR");
|
||||
|
||||
ContainerBox iron_box(Vector3f(1000, 1000, 1000));
|
||||
Geant::BoxSolid* iron_cube = new Geant::BoxSolid("IronCube", &iron_box);
|
||||
iron_cube->SetNistMaterial("G4_Fe");
|
||||
iron_cube->Update();
|
||||
scene.AddSolid(iron_cube);
|
||||
|
||||
RandomEmitter* emitter = new RandomEmitter();
|
||||
scene.SetEmitter(emitter);
|
||||
scene.Initialize();
|
||||
|
||||
// 2. Setup VTK Viewer
|
||||
Vtk::Viewer viewer;
|
||||
viewer.GetRenderer()->SetBackground(0.05, 0.05, 0.1);
|
||||
|
||||
// Visualize iron cube
|
||||
Vtk::vtkContainerBox* vtkIron = new Vtk::vtkContainerBox(&iron_box);
|
||||
viewer.AddPuppet(*vtkIron);
|
||||
|
||||
// 3. Event Handling
|
||||
AppState state = { &scene, &viewer, {} };
|
||||
|
||||
vtkSmartPointer<vtkCallbackCommand> keyCallback = vtkSmartPointer<vtkCallbackCommand>::New();
|
||||
keyCallback->SetCallback(KeyPressCallbackFunction);
|
||||
keyCallback->SetClientData(&state);
|
||||
|
||||
viewer.GetInteractor()->AddObserver(vtkCommand::KeyPressEvent, keyCallback);
|
||||
|
||||
std::cout << "=================================================" << std::endl;
|
||||
std::cout << " Geant Muon Simulation Viewer" << std::endl;
|
||||
std::cout << " Press [ENTER] to fire a new random muon" << std::endl;
|
||||
std::cout << " Press [q] to exit" << std::endl;
|
||||
std::cout << "=================================================" << std::endl;
|
||||
|
||||
viewer.ZoomAuto();
|
||||
viewer.Start();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user