geant events for multiple scattering

This commit is contained in:
AndreaRigoni
2026-03-14 23:33:31 +00:00
parent 692cdf7ae3
commit c63a1ae047
18 changed files with 681 additions and 90 deletions

View File

@@ -0,0 +1,17 @@
################################################################################
##### Vtk/HEP/Geant - VTK wrappers for HEP Geant objects #######################
################################################################################
set(HEP_GEANT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantEvent.cpp
PARENT_SCOPE)
set(HEP_GEANT_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantEvent.h
PARENT_SCOPE)
if(BUILD_TESTING)
include(uLibTargetMacros)
add_subdirectory(testing)
endif()

View File

@@ -0,0 +1,14 @@
# TESTS
set(TESTS
vtkGeantEventTest
)
set(LIBRARIES
${PACKAGE_LIBPREFIX}Core
${PACKAGE_LIBPREFIX}Math
${PACKAGE_LIBPREFIX}Geant
${PACKAGE_LIBPREFIX}Vtk
Eigen3::Eigen
)
uLib_add_tests(VtkGeant)

View 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;
}

View File

@@ -0,0 +1,108 @@
/*//////////////////////////////////////////////////////////////////////////////
// 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 "vtkGeantEvent.h"
#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkSmartPointer.h>
namespace uLib {
namespace Vtk {
vtkGeantEvent::vtkGeantEvent(Content *content)
: m_MuonPath(vtkActor::New()), m_Content(content) {
this->InstallPipe();
this->Update();
}
vtkGeantEvent::~vtkGeantEvent() {
m_MuonPath->Delete();
}
vtkPolyData *vtkGeantEvent::GetPolyData() const {
if (!m_MuonPath || !m_MuonPath->GetMapper())
return NULL;
return vtkPolyData::SafeDownCast(m_MuonPath->GetMapper()->GetInput());
}
void vtkGeantEvent::Update() {
if (!m_Content)
return;
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
const HLine3f &gen = m_Content->GenVector();
const Vector<Geant::GeantEvent::Delta> &path = m_Content->Path();
// Start point from generation vector
Vector3f currentPos(gen.origin(0), gen.origin(1), gen.origin(2));
points->InsertNextPoint(currentPos(0), currentPos(1), currentPos(2));
for (size_t i = 0; i < path.size(); ++i) {
const Geant::GeantEvent::Delta &delta = path[i];
// P_{i+1} = P_i + Length * Direction
// Note: HVector3f is stored as (x,y,z,0) in HPoint3f template
Vector3f dir(delta.Direction()(0), delta.Direction()(1), delta.Direction()(2));
currentPos += delta.GetLength() * dir;
points->InsertNextPoint(currentPos(0), currentPos(1), currentPos(2));
vtkIdType line[2] = {static_cast<vtkIdType>(i),
static_cast<vtkIdType>(i + 1)};
lines->InsertNextCell(2, line);
}
vtkPolyData *polyData = GetPolyData();
if (polyData) {
polyData->SetPoints(points);
polyData->SetLines(lines);
polyData->Modified();
}
}
void vtkGeantEvent::InstallPipe() {
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
m_MuonPath->SetMapper(mapper);
// Set default look: Red line
m_MuonPath->GetProperty()->SetColor(1.0, 0.0, 0.0);
m_MuonPath->GetProperty()->SetLineWidth(2.0);
m_MuonPath->GetProperty()->SetAmbient(1.0);
this->SetProp(m_MuonPath);
}
} // namespace Vtk
} // namespace uLib

View File

@@ -0,0 +1,57 @@
/*//////////////////////////////////////////////////////////////////////////////
// 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.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_VTKGEANTEVENT_H
#define U_VTKGEANTEVENT_H
#include "HEP/Geant/GeantEvent.h"
#include "uLibVtkInterface.h"
#include <vtkActor.h>
namespace uLib {
namespace Vtk {
class vtkGeantEvent : public Puppet, public Polydata {
typedef Geant::GeantEvent Content;
public:
vtkGeantEvent(Content *content);
~vtkGeantEvent();
virtual class vtkPolyData *GetPolyData() const override;
virtual void Update();
protected:
virtual void InstallPipe();
vtkActor *m_MuonPath;
Content *m_Content;
};
} // namespace Vtk
} // namespace uLib
#endif // U_VTKGEANTEVENT_H