/*////////////////////////////////////////////////////////////////////////////// // 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 "Vtk/HEP/Geant/vtkGeantEvent.h" #include "HEP/Geant/Scene.h" #include "HEP/Geant/EmitterPrimary.hh" #include "Vtk/Math/vtkContainerBox.h" #include "Vtk/Math/vtkDense.h" #include "Math/Units.h" #include "Vtk/uLibVtkViewer.h" #include "Vtk/HEP/Geant/vtkGeantEvent.h" #include "Vtk/Math/vtkContainerBox.h" #include #include #include #include #include #include #include #include #include #include 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 on the top face of the world box (z = 15m) double x = 0_m; double y = 0_m; double z = 14.9_m; // Top face fParticleGun->SetParticlePosition(G4ThreeVector(x, y, z)); // Aim at a random point on the bottom face (z = -15m) double tx = 0_m; double ty = 0_m; double tz = -14.9_m; // Bottom face G4ThreeVector dir(tx - x, ty - y, tz - z); fParticleGun->SetParticleMomentumDirection(dir.unit()); fParticleGun->SetParticleEnergy(15_GeV); fParticleGun->GeneratePrimaryVertex(anEvent); } }; struct AppState { Geant::Scene* scene; Vtk::Viewer* viewer; Vector results; }; void KeyPressCallbackFunction(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData) { auto* interactor = static_cast(caller); auto* state = static_cast(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::GeantEvent* vtkEvent = new Vtk::GeantEvent(lastEvent); state->viewer->AddProp3D(*vtkEvent); // Re-render state->viewer->GetRenderer()->Render(); state->viewer->GetRenderWindow()->Render(); } else { std::cout << " No event collected." << std::endl; } } } int main(int argc, char** argv) { // 1. Setup Geant4 Scene Geant::Scene scene; scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR"); ContainerBox iron_box; iron_box.Scale(Vector3f(10_m, 10_m, 10_m)); iron_box.SetPosition(Vector3f(-5_m, -5_m, -5_m)); 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 world box Vtk::ContainerBox* vtkWorld = new Vtk::ContainerBox(scene.GetWorldBox()); // vtkWorld->ShowBoundingBox(true); vtkWorld->ShowScaleMeasures(true); viewer.AddProp3D(*vtkWorld); // Visualize iron cube Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box); vtkIron->SetOpacity(0.2); vtkIron->SetRepresentation(Vtk::Prop3D::Surface); viewer.AddProp3D(*vtkIron); // 3. Event Handling AppState state = { &scene, &viewer, {} }; vtkSmartPointer keyCallback = vtkSmartPointer::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; }