add geant4 scene and gcompose app

This commit is contained in:
AndreaRigoni
2026-03-13 17:19:51 +00:00
parent f2133c31d5
commit 61052f80bc
34 changed files with 1341 additions and 580 deletions

View File

@@ -3,7 +3,12 @@
##### CMAKE LISTS ############################################################## ##### CMAKE LISTS ##############################################################
################################################################################ ################################################################################
if(EXISTS "${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
include("${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
endif()
cmake_minimum_required (VERSION 3.26) cmake_minimum_required (VERSION 3.26)
if(POLICY CMP0167) if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW) cmake_policy(SET CMP0167 NEW)
endif() endif()
@@ -107,6 +112,8 @@ set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF) set(Boost_USE_STATIC_RUNTIME OFF)
message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}") message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}")
find_package(HDF5 REQUIRED CONFIG)
find_package(Boost 1.45.0 COMPONENTS program_options serialization unit_test_framework REQUIRED) find_package(Boost 1.45.0 COMPONENTS program_options serialization unit_test_framework REQUIRED)
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
@@ -120,6 +127,9 @@ include(${ROOT_USE_FILE})
find_package(VTK REQUIRED) find_package(VTK REQUIRED)
# include(${VTK_USE_FILE}) # include(${VTK_USE_FILE})
set(GEANT4_USE_HDF5 OFF CACHE BOOL "Use HDF5" FORCE)
find_package(Geant4 REQUIRED)
find_package(pybind11 REQUIRED) find_package(pybind11 REQUIRED)
@@ -216,7 +226,7 @@ add_subdirectory(${SRC_DIR}/Vtk)
add_subdirectory(${SRC_DIR}/Python) add_subdirectory(${SRC_DIR}/Python)
#add_subdirectory("${SRC_DIR}/utils/make_recipe") add_subdirectory(app)
## Documentation and packages ## Documentation and packages

1
app/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
add_subdirectory(gcompose)

View File

@@ -0,0 +1,20 @@
add_executable(gcompose src/main.cpp)
target_include_directories(gcompose PRIVATE
${SRC_DIR}
${PROJECT_BINARY_DIR}
${Geant4_INCLUDE_DIRS}
${VTK_INCLUDE_DIRS}
)
target_link_libraries(gcompose
mutomCore
mutomMath
mutomGeant
mutomVtk
${Geant4_LIBRARIES}
${VTK_LIBRARIES}
)
install(TARGETS gcompose RUNTIME DESTINATION bin)

45
app/gcompose/src/main.cpp Normal file
View File

@@ -0,0 +1,45 @@
#include "Math/ContainerBox.h"
#include <HEP/Geant/Scene.h>
#include <Vtk/uLibVtkViewer.h>
#include <Vtk/vtkContainerBox.h>
#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <iostream>
using namespace uLib;
int main(int argc, char** argv) {
std::cout << "Starting gcompose application..." << std::endl;
uLib::ContainerBox world_box(Vector3f(100, 100, 100));
uLib::Scene scene;
scene.ConstructWorldBox(&world_box, "G4_AIR");
scene.Initialize();
// 2. Initialize VTK Viewer
Vtk::Viewer viewer;
uLib::Vtk::vtkContainerBox vtk_box(&world_box);
viewer.AddPuppet(vtk_box);
viewer.GetRenderer()->Render();
std::cout << "Geant4 and VTK scenes are ready." << std::endl;
std::cout << "Starting VTK Interactor..." << std::endl;
// 3. Start VTK interactor (blocks until window is closed)
viewer.Start();
// 4. Clean up
std::cout << "Shutting down..." << std::endl;
return 0;
}

View File

@@ -1,8 +1,13 @@
[requires] [requires]
eigen/3.4.0 eigen/3.4.0
boost/1.83.0 boost/1.83.0
pybind11/3.0.2 # pybind11/3.0.2
hdf5/1.14.3
[generators] [generators]
CMakeDeps CMakeDeps
CMakeToolchain CMakeToolchain
[options]
hdf5/*:threadsafe=True
hdf5/*:enable_unsupported=True

View File

@@ -7,6 +7,7 @@ include_directories(${SRC_DIR}/HEP)
add_subdirectory(Detectors) add_subdirectory(Detectors)
add_subdirectory(Geant) add_subdirectory(Geant)
# add_subdirectory(MuonTomography)
set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} PARENT_SCOPE) set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} PARENT_SCOPE)
set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} PARENT_SCOPE) set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} PARENT_SCOPE)

View File

@@ -29,8 +29,8 @@
#define U_CHAMBERHITEVENT_H #define U_CHAMBERHITEVENT_H
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Hit.h" #include "Detectors/HitMC.h"
#include "ChamberDetector.h" #include "Detectors/DetectorChamber.h"
namespace uLib { namespace uLib {
@@ -38,17 +38,17 @@ class ChamberHitEventData
{ {
public: public:
uLibConstRefMacro (Hits, Vector<HitData> ) uLibConstRefMacro (Hits, Vector<HitData> )
uLibGetMacro (Idv, ChamberDetector::ID) uLibGetMacro (Idv, uint)
private: private:
friend class ChamberHitEvent; friend class ChamberHitEvent;
Vector<HitData> m_Hits; Vector<HitData> m_Hits;
DetectorChamber::ID m_Idv; // -> chamber/view uint m_Idv; // -> chamber/view
}; };
class ChamberHitEvent : public ChamberHitEventData { class ChamberHitEvent : public ChamberHitEventData {
public: public:
uLibRefMacro (Hits, Vector<HitData> ) uLibRefMacro (Hits, Vector<HitData> )
uLibSetMacro (Idv, ChamberDetector::ID) uLibSetMacro (Idv, uint)
}; };
} }

View File

@@ -33,9 +33,6 @@
namespace uLib { namespace uLib {
class HitRawCode_CMSDrift : class HitRawCode_CMSDrift :
public BitCode4<unsigned short,6,3,2,5> public BitCode4<unsigned short,6,3,2,5>
{ {
@@ -59,8 +56,14 @@ public:
}; };
class HitData {
public:
HitData() {}
~HitData() {}
};

View File

@@ -0,0 +1,25 @@
#include "ActionInitialization.hh"
#include "EmitterPrimary.hh"
ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {}
ActionInitialization::~ActionInitialization() {}
void ActionInitialization::BuildForMaster() const {
// Questo metodo viene usato in modalità Multi-Threading.
// Serve per le azioni che devono esistere solo nel thread Master
// (tipicamente solo per inizializzare file di output o il RunAction globale).
// Esempio: SetUserAction(new RunAction());
}
void ActionInitialization::Build() const {
// Questo è il cuore dell'inizializzazione per i thread di lavoro.
// Qui passiamo il nostro generatore di muoni a Geant4.
SetUserAction(new EmitterPrimary());
// In una simulazione completa, qui registreresti anche le altre classi:
// SetUserAction(new RunAction());
// SetUserAction(new EventAction());
// SetUserAction(new SteppingAction());
}

View File

@@ -0,0 +1,18 @@
#ifndef ActionInitialization_h
#define ActionInitialization_h
#include "G4VUserActionInitialization.hh"
class ActionInitialization : public G4VUserActionInitialization {
public:
ActionInitialization();
~ActionInitialization();
// Metodo chiamato solo dal thread principale (Master)
virtual void BuildForMaster() const;
// Metodo chiamato dai thread di lavoro (Worker) o in modalità sequenziale
virtual void Build() const;
};
#endif

View File

@@ -3,8 +3,6 @@
##### HEP/Geant - Geant4 integration library ################################### ##### HEP/Geant - Geant4 integration library ###################################
################################################################################ ################################################################################
find_package(Geant4 QUIET)
if(NOT Geant4_FOUND) if(NOT Geant4_FOUND)
message(STATUS "Geant4 not found - skipping mutomGeant library") message(STATUS "Geant4 not found - skipping mutomGeant library")
return() return()
@@ -18,11 +16,18 @@ set(HEADERS
Matter.h Matter.h
Scene.h Scene.h
Solid.h Solid.h
DetectorConstruction.hh
PhysicsList.hh
ActionInitialization.hh
) )
set(SOURCES set(SOURCES
Scene.cpp Scene.cpp
Solid.cpp Solid.cpp
EmitterPrimary.cpp
DetectorConstruction.cpp
PhysicsList.cpp
ActionInitialization.cpp
) )
set(libname ${PACKAGE_LIBPREFIX}Geant) set(libname ${PACKAGE_LIBPREFIX}Geant)
@@ -50,3 +55,8 @@ install(TARGETS ${libname}
install(FILES ${HEADERS} install(FILES ${HEADERS}
DESTINATION ${INSTALL_INC_DIR}/HEP/Geant) DESTINATION ${INSTALL_INC_DIR}/HEP/Geant)
if(BUILD_TESTING)
include(uLibTargetMacros)
add_subdirectory(testing)
endif()

View File

@@ -0,0 +1,29 @@
#include "DetectorConstruction.hh"
#include "Core/Object.h"
#include "Math/ContainerBox.h"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4NistManager.hh"
#include "G4PVPlacement.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
namespace uLib {
DetectorConstruction::DetectorConstruction(const char *name) : G4VUserDetectorConstruction() {}
DetectorConstruction::~DetectorConstruction() {}
G4VPhysicalVolume *DetectorConstruction::Construct() { return nullptr; }
void DetectorConstruction::ConstructSDandField() {}
}

View File

@@ -0,0 +1,28 @@
#ifndef DetectorConstruction_h
#define DetectorConstruction_h
#include "Core/Object.h"
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
class G4VPhysicalVolume;
class G4LogicalVolume;
namespace uLib {
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction(const char *name);
virtual ~DetectorConstruction();
virtual G4VPhysicalVolume *Construct();
virtual void ConstructSDandField();
};
} // namespace uLib
#endif

View File

@@ -0,0 +1,50 @@
#include "EmitterPrimary.hh"
#include "G4Box.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
#include "Randomize.hh"
EmitterPrimary::EmitterPrimary()
: G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr) {
// Creiamo il ParticleGun impostandolo per sparare 1 particella alla volta
G4int n_particle = 1;
fParticleGun = new G4ParticleGun(n_particle);
// Otteniamo la tabella delle particelle di Geant4
G4ParticleTable *particleTable = G4ParticleTable::GetParticleTable();
// Cerchiamo il muone negativo (usa "mu+" per l'antimuone)
G4String particleName = "mu-";
G4ParticleDefinition *particle = particleTable->FindParticle(particleName);
// Configuriamo le proprietà iniziali della particella
fParticleGun->SetParticleDefinition(particle);
// Impostiamo la direzione della quantità di moto (es. lungo l'asse Z)
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., -1.));
// Impostiamo l'energia cinetica a 1 GeV
fParticleGun->SetParticleEnergy(1.0 * GeV);
// Impostiamo la posizione di partenza (origine)
fParticleGun->SetParticlePosition(G4ThreeVector(0., 0., 10. * m));
}
EmitterPrimary::~EmitterPrimary() {
// Importante: liberare la memoria
delete fParticleGun;
}
void EmitterPrimary::GeneratePrimaries(G4Event *anEvent) {
// Questo metodo viene invocato all'inizio di ogni evento.
// Qui potresti anche aggiungere una randomizzazione della posizione o
// dell'energia.
fParticleGun->GeneratePrimaryVertex(anEvent);
}

View File

@@ -0,0 +1,23 @@
#ifndef U_GEANT_EMITTERPRIMARY_HH
#define U_GEANT_EMITTERPRIMARY_HH 1
#include "G4VUserPrimaryGeneratorAction.hh"
#include "globals.hh"
class G4ParticleGun;
class G4Event;
class EmitterPrimary : public G4VUserPrimaryGeneratorAction
{
public:
EmitterPrimary();
virtual ~EmitterPrimary();
// Metodo principale chiamato all'inizio di ogni evento
virtual void GeneratePrimaries(G4Event*);
private:
G4ParticleGun* fParticleGun; // Puntatore al cannone di particelle
};
#endif

View File

@@ -30,17 +30,18 @@
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Math/Dense.h" #include "Math/Dense.h"
#include "ChamberHitEvent.h" #include "Detectors/ChamberHitEvent.h"
namespace uLib { namespace uLib {
class GeantEventData { class GeantEventData {
public: public:
uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf) uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf)
uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f) uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f)
uLibConstRefMacro(ChEvents, Vector<ChamberHitEventData>) uLibConstRefMacro(ChEvents, Vector<ChamberHitEventData>)
private : friend class GeantEvent; private:
friend class GeantEvent;
Id_t m_EventID; Id_t m_EventID;
Scalarf m_Momentum; Scalarf m_Momentum;
Vector3f m_GenPos; Vector3f m_GenPos;
@@ -48,7 +49,7 @@ uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf)
Vector<ChamberHitEventData> m_ChEvents; Vector<ChamberHitEventData> m_ChEvents;
}; };
class GeantEvent { class GeantEvent : public GeantEventData {
public: public:
uLibSetMacro(EventID, Id_t) uLibSetMacro(Momentum, Scalarf) uLibSetMacro(EventID, Id_t) uLibSetMacro(Momentum, Scalarf)
uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f) uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f)

View File

@@ -0,0 +1,22 @@
#include "PhysicsList.hh"
#include "G4DecayPhysics.hh"
#include "G4EmStandardPhysics.hh"
#include "G4RadioactiveDecayPhysics.hh"
PhysicsList::PhysicsList() : G4VModularPhysicsList() {
SetVerboseLevel(1);
// Default physics
RegisterPhysics(new G4DecayPhysics());
// EM physics
RegisterPhysics(new G4EmStandardPhysics());
// Radioactive decay
RegisterPhysics(new G4RadioactiveDecayPhysics());
}
PhysicsList::~PhysicsList() {}
void PhysicsList::SetCuts() { G4VModularPhysicsList::SetCuts(); }

View File

@@ -0,0 +1,14 @@
#ifndef PhysicsList_h
#define PhysicsList_h
#include "G4VModularPhysicsList.hh"
class PhysicsList : public G4VModularPhysicsList {
public:
PhysicsList();
virtual ~PhysicsList();
virtual void SetCuts();
};
#endif

View File

@@ -23,52 +23,127 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <Geant4/G4Box.hh>
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4Material.hh> #include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh> #include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh> #include <Geant4/G4PVPlacement.hh>
#include <Geant4/G4RunManager.hh>
#include <Geant4/G4RunManagerFactory.hh>
#include <Geant4/G4SystemOfUnits.hh>
#include <Geant4/G4VPhysicalVolume.hh>
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Matter.h" #include "HEP/Geant/DetectorConstruction.hh"
#include "Math/ContainerBox.h"
#include "Math/Dense.h"
#include "Solid.h" #include "Solid.h"
#include "Scene.h" #include "Scene.h"
#include "PhysicsList.hh"
#include "ActionInitialization.hh"
namespace uLib { namespace uLib {
class SceneDetectorConstruction : public DetectorConstruction {
class DetectorsScenePimpl {
public: public:
SceneDetectorConstruction(class SceneImpl *owner);
G4VPhysicalVolume *Construct() override;
// members // private:
//Vector<Solid> m_Solids; class SceneImpl *m_Owner;
}; };
class SceneImpl {
public:
// constructor //
SceneImpl() : m_RunManager(G4RunManagerFactory::CreateRunManager()) {}
// destructor //
~SceneImpl() {
if (m_RunManager) delete m_RunManager;
if (m_World) delete m_World;
}
void Initialize() {
// Set mandatory initialization classes for Geant4
m_RunManager->SetUserInitialization(new SceneDetectorConstruction(this));
m_RunManager->SetUserInitialization(new PhysicsList);
m_RunManager->SetUserInitialization(new ActionInitialization);
DetectorsScene::DetectorsScene() : // Initialize Geant4
d(new DetectorsScenePimpl()) m_RunManager->Initialize();
{} }
DetectorsScene::~DetectorsScene() // members //
{ Vector<Solid *> m_Solids;
delete d; Solid *m_World = nullptr;
} G4RunManager *m_RunManager;
};
void DetectorsScene::AddSolid(const Solid &solid) SceneDetectorConstruction::SceneDetectorConstruction(SceneImpl *owner)
{ : DetectorConstruction("Scene"), m_Owner(owner) {}
// d->m_Solids.push_back(solid);
G4VPhysicalVolume *SceneDetectorConstruction::Construct() {
return m_Owner->m_World->GetPhysical();
} }
Scene::Scene() : d(new SceneImpl()) {}
Scene::~Scene() { delete d; }
void Scene::AddSolid(Solid *solid, Solid *parent) {
d->m_Solids.push_back(solid);
if (!d->m_World) {
d->m_World = solid;
} else {
solid->SetParent(parent ? parent : d->m_World);
}
} }
void Scene::ConstructWorldBox(const ContainerBox *box, const char *material) {
// Get nist material manager
if (!d->m_World) {
d->m_World = new Solid("World");
d->m_World->SetNistMaterial(material);
AddSolid(d->m_World);
}
Vector3f size = box->GetSize();
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);
d->m_World->SetPhysical(physWorld);
Matrix4f transform = box->GetMatrix();
d->m_World->SetTransform(transform);
}
void Scene::Initialize() {
d->Initialize();
}
} // namespace uLib

View File

@@ -23,30 +23,33 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef SCENE_H #ifndef SCENE_H
#define SCENE_H #define SCENE_H
#include "Core/Object.h" #include "Core/Object.h"
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Solid.h" #include "Solid.h"
class G4VPhysicalVolume;
namespace uLib { namespace uLib {
class Scene : public Object {
class DetectorsScene : public Object {
public: public:
DetectorsScene(); Scene();
~DetectorsScene(); ~Scene();
void AddSolid(Solid *solid, Solid *parent = nullptr);
void AddSolid(const Solid &solid); void ConstructWorldBox(const ContainerBox *box, const char *material);
void Initialize();
private: private:
class DetectorsScenePimpl *d; class SceneImpl *d;
}; };
} // namespace uLib
}
#endif // SCENE_H #endif // SCENE_H

View File

@@ -23,20 +23,21 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
// G4 Solid // // G4 Solid //
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4Material.hh> #include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh> #include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh>
// Tessellated solid // // Tessellated solid //
#include <Geant4/G4TessellatedSolid.hh> #include <Geant4/G4TessellatedSolid.hh>
#include <Geant4/G4TriangularFacet.hh>
#include <Geant4/G4ThreeVector.hh> #include <Geant4/G4ThreeVector.hh>
#include <Geant4/G4TriangularFacet.hh>
#include <Geant4/G4Box.hh>
#include <Geant4/G4PVPlacement.hh>
#include "Math/Dense.h" #include "Math/Dense.h"
#include "Math/Transform.h"
#include "Solid.h" #include "Solid.h"
@@ -45,41 +46,84 @@ namespace uLib {
class DetectorsSolidPimpl { class DetectorsSolidPimpl {
public: public:
static G4ThreeVector getG4Vector3f(const Vector3f &vector) { static G4ThreeVector getG4Vector3f(const Vector3f &vector) {
return G4ThreeVector( vector(0), vector(1), vector(2) ); return G4ThreeVector(vector(0), vector(1), vector(2));
} }
}; };
Solid::Solid()
: m_Logical(new G4LogicalVolume(NULL, NULL, "unnamed_solid")),
m_Material(NULL) {}
Solid::Solid(const char *name)
: m_Logical(new G4LogicalVolume(NULL, NULL, name)), m_Material(NULL) {}
Solid::Solid() : void Solid::SetNistMaterial(const char *name) {
m_Logical (new G4LogicalVolume(NULL,NULL,"unnamed_solid")),
m_Material(NULL)
{}
Solid::Solid(const char *name) :
m_Logical(new G4LogicalVolume(NULL,NULL,name)),
m_Material(NULL)
{}
void Solid::SetNistMaterial(const char *name)
{
G4NistManager *nist = G4NistManager::Instance(); G4NistManager *nist = G4NistManager::Instance();
if (m_Material) delete m_Material;
m_Material = nist->FindOrBuildMaterial(name); m_Material = nist->FindOrBuildMaterial(name);
m_Logical->SetMaterial(m_Material); m_Logical->SetMaterial(m_Material);
} }
void Solid::SetMaterial(G4Material *material) void Solid::SetMaterial(G4Material *material) {
{ if (material) {
if(material)
{
m_Material = material; m_Material = material;
m_Logical->SetMaterial(material); m_Logical->SetMaterial(material);
} }
} }
void Solid::SetTransform(Matrix4f transform) {
uLib::AffineTransform t;
t.SetMatrix(transform);
// 2. Extracto position and rotation for Geant4
Vector3f pos = t.GetPosition();
G4ThreeVector g4pos(pos(0), pos(1), pos(2));
// Create a G4 rotation matrix from the 4x4 matrix
Matrix3f m = t.GetRotation();
G4RotationMatrix* rot = new G4RotationMatrix();
rot->set(G4ThreeVector(m(0,0), m(1,0), m(2,0)),
G4ThreeVector(m(0,1), m(1,1), m(2,1)),
G4ThreeVector(m(0,2), m(1,2), m(2,2)));
// 3. Se l'oggetto è già stato piazzato, aggiorniamo la sua trasformazione
if (m_Physical) {
m_Physical->SetTranslation(g4pos);
m_Physical->SetRotation(rot);
}
}
void Solid::SetParent(Solid *parent) {
if (!m_Logical) {
std::cerr << "logical volume not created for solid " << GetName() << std::endl;
return;
}
if(m_Physical) {
std::cerr << "physical volume already created for solid " << GetName() << std::endl;
return;
}
G4LogicalVolume* parentLogical = nullptr;
if (parent) {
parentLogical = parent->GetLogical();
if (!parentLogical) {
std::cerr << "parent logical volume not created for solid " << parent->GetName() << std::endl;
return;
}
}
// G4PVPlacement
m_Physical = new G4PVPlacement(
nullptr, // Rotation
G4ThreeVector(0,0,0), // Position (translation) inside the parent
m_Logical, // The logical volume of this solid (the child)
GetName(), // Name of the physical volume
parentLogical, // The logical volume of the parent (nullptr if it's the World volume)
false, // Boolean operations (usually false)
0, // Copy number
true // Check overlaps (useful to enable in debug phase)
);
}
@@ -87,28 +131,44 @@ void Solid::SetMaterial(G4Material *material)
TessellatedSolid::TessellatedSolid(const char *name)
: BaseClass(name), m_Solid(new G4TessellatedSolid(name)) {}
void TessellatedSolid::SetMesh(TriangleMesh &mesh) {
TessellatedSolid::TessellatedSolid(const char *name) :
BaseClass(name),
m_Solid(new G4TessellatedSolid(name))
{}
void TessellatedSolid::SetMesh(TriangleMesh &mesh)
{
G4TessellatedSolid *ts = this->m_Solid; G4TessellatedSolid *ts = this->m_Solid;
for (int i=0; i<mesh.Triangles().size(); ++i) { for (int i = 0; i < mesh.Triangles().size(); ++i) {
const Vector3i &trg = mesh.Triangles().at(i); const Vector3i &trg = mesh.Triangles().at(i);
G4TriangularFacet *facet = new G4TriangularFacet( G4TriangularFacet *facet = new G4TriangularFacet(
DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(0))), DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(0))),
DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(1))), DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(1))),
DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(2))), DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(2))), ABSOLUTE);
ABSOLUTE);
ts->AddFacet((G4VFacet *)facet); ts->AddFacet((G4VFacet *)facet);
} }
this->m_Logical->SetSolid(ts); this->m_Logical->SetSolid(ts);
} }
BoxSolid::BoxSolid(const char *name, ContainerBox *box) : BaseClass(name) {
m_Solid = new G4Box(name, 0.5, 0.5, 0.5);
m_Object = box;
Object::connect(box, &ContainerBox::Updated, this, &BoxSolid::Update);
this->m_Logical->SetSolid(m_Solid);
} }
void BoxSolid::Update() {
if (m_Object) {
Vector3f size = m_Object->GetSize();
m_Solid->SetXHalfLength(size(0) * 0.5);
m_Solid->SetYHalfLength(size(1) * 0.5);
m_Solid->SetZHalfLength(size(2) * 0.5);
this->SetTransform(m_Object->GetMatrix());
// this->m_Logical->SetSolid(m_Solid);
}
}
} // namespace uLib

View File

@@ -23,39 +23,51 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef SOLID_H #ifndef SOLID_H
#define SOLID_H #define SOLID_H
#include "Core/Object.h" #include "Core/Object.h"
#include "Geant/Matter.h"
#include <Geant4/G4LogicalVolume.hh>
#include "Math/ContainerBox.h"
#include "Math/Dense.h" #include "Math/Dense.h"
#include "Math/TriangleMesh.h" #include "Math/TriangleMesh.h"
#include "Detectors/Matter.h"
class G4Material; class G4Material;
class G4LogicalVolume; class G4LogicalVolume;
class G4TessellatedSolid; class G4TessellatedSolid;
class G4Box;
namespace uLib { namespace uLib {
class Solid : public Object { class Solid : public Object {
public: public:
Solid(); Solid();
Solid(const char *name); Solid(const char *name);
void SetNistMaterial(const char *name); void SetNistMaterial(const char *name);
void SetMaterial(G4Material *material); void SetMaterial(G4Material *material);
uLibGetMacro(Material,G4Material *) // Implementiamo SetParent qui, per tutti.
uLibGetMacro(Logical,G4LogicalVolume *) virtual void SetParent(Solid *parent);
// Setters per la posizione (necessari per il piazzamento)
void SetTransform(Matrix4f transform);
uLibGetMacro(Material, G4Material *)
uLibGetSetMacro(Logical, G4LogicalVolume *)
uLibGetSetMacro(Physical, G4VPhysicalVolume *)
inline const char *GetName() const { return m_Logical->GetName().c_str(); }
protected: protected:
G4Material *m_Material; G4Material *m_Material;
G4LogicalVolume *m_Logical; G4LogicalVolume *m_Logical;
G4VPhysicalVolume *m_Physical; // <-- Memorizza l'oggetto posizionato
G4ThreeVector *m_Position; // <-- Offset rispetto al centro del padre
G4RotationMatrix* m_Rotation; // <-- Rotazione rispetto al padre
}; };
@@ -64,23 +76,37 @@ protected:
class TessellatedSolid : public Solid { class TessellatedSolid : public Solid {
typedef Solid BaseClass; typedef Solid BaseClass;
public: public:
TessellatedSolid(const char *name); TessellatedSolid(const char *name);
void SetMesh(TriangleMesh &mesh); void SetMesh(TriangleMesh &mesh);
uLibGetMacro(Solid, G4TessellatedSolid *)
uLibGetMacro(Solid,G4TessellatedSolid *) public slots:
private: void Update();
private :
G4TessellatedSolid *m_Solid; G4TessellatedSolid *m_Solid;
}; };
}
class BoxSolid : public Solid {
typedef Solid BaseClass;
public:
BoxSolid(const char *name, ContainerBox *box);
public slots:
void Update();
private:
ContainerBox *m_Object;
G4Box *m_Solid;
};
} // namespace uLib
#endif // SOLID_H #endif // SOLID_H

View File

@@ -0,0 +1,23 @@
#include "HEP/Geant/ActionInitialization.hh" // Il file appena creato
#include "G4RunManagerFactory.hh" // Per il RunManager moderno
// ... altri include (DetectorConstruction, PhysicsList, ecc.)
int main(int argc, char **argv) {
// Creazione del Run Manager
auto *runManager = G4RunManagerFactory::CreateRunManager();
// 1. Inizializzazione della Geometria
// runManager->SetUserInitialization(new DetectorConstruction());
// 2. Inizializzazione della Fisica
// runManager->SetUserInitialization(new PhysicsList());
// 3. INIZIALIZZAZIONE DELLE AZIONI (Il nostro generatore!)
runManager->SetUserInitialization(new ActionInitialization());
// ... Inizializzazione del kernel ( runManager->Initialize(); ), UI manager,
// vis manager, ecc.
delete runManager;
return 0;
}

View File

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

View File

@@ -0,0 +1,72 @@
#include "Geant/Solid.h"
#include "HEP/Geant/GeantEvent.h"
#include "Math/TriangleMesh.h"
#include "testing-prototype.h"
#include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4TessellatedSolid.hh>
#include <string.h>
using namespace uLib;
int main() {
BEGIN_TESTING(Geant Event);
// Test Solid initialization and NIST material //
{
Solid solid("test_solid");
TEST1(solid.GetLogical() != nullptr);
solid.SetNistMaterial("G4_AIR");
TEST1(solid.GetMaterial() != nullptr);
TEST1(solid.GetMaterial()->GetName() == "G4_AIR");
}
// Test TessellatedSolid with a simple mesh //
{
TessellatedSolid tsolid("test_tessellated");
TEST1(tsolid.GetLogical() != nullptr);
TEST1(tsolid.GetSolid() != nullptr);
// cube mesh //
TriangleMesh mesh;
mesh.AddPoint(Vector3f(0,0,0));
mesh.AddPoint(Vector3f(1,0,0));
mesh.AddPoint(Vector3f(0,1,0));
mesh.AddPoint(Vector3f(1,1,0));
mesh.AddPoint(Vector3f(0,0,1));
mesh.AddPoint(Vector3f(1,0,1));
mesh.AddPoint(Vector3f(0,1,1));
mesh.AddPoint(Vector3f(1,1,1));
// create triangles (consistent outward winding) //
// bottom (z=0)
mesh.AddTriangle(Vector3i(0,2,3));
mesh.AddTriangle(Vector3i(0,3,1));
// top (z=1)
mesh.AddTriangle(Vector3i(4,5,7));
mesh.AddTriangle(Vector3i(4,7,6));
// left (x=0)
mesh.AddTriangle(Vector3i(0,4,6));
mesh.AddTriangle(Vector3i(0,6,2));
// right (x=1)
mesh.AddTriangle(Vector3i(1,3,7));
mesh.AddTriangle(Vector3i(1,7,5));
// front (y=0)
mesh.AddTriangle(Vector3i(0,1,5));
mesh.AddTriangle(Vector3i(0,5,4));
// back (y=1)
mesh.AddTriangle(Vector3i(2,6,7));
mesh.AddTriangle(Vector3i(2,7,3));
tsolid.SetMesh(mesh);
// GeantEvent geant_event;
}
END_TESTING
}

View File

@@ -0,0 +1,18 @@
#include "Math/ContainerBox.h"
#include "Math/Dense.h"
#include "HEP/Geant/Scene.h"
using namespace uLib;
int main() {
uLib::ContainerBox world_box(Vector3f(100, 100, 100));
uLib::Scene scene;
scene.ConstructWorldBox(&world_box, "G4_AIR");
scene.Initialize();
return 0;
}

View File

@@ -0,0 +1,69 @@
#include "Geant/Solid.h"
#include "Math/TriangleMesh.h"
#include "testing-prototype.h"
#include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4TessellatedSolid.hh>
#include <string.h>
using namespace uLib;
int main() {
BEGIN_TESTING(Geant Solid);
// Test Solid initialization and NIST material //
{
Solid solid("test_solid");
TEST1(solid.GetLogical() != nullptr);
solid.SetNistMaterial("G4_AIR");
TEST1(solid.GetMaterial() != nullptr);
TEST1(solid.GetMaterial()->GetName() == "G4_AIR");
}
// Test TessellatedSolid with a simple mesh //
{
TessellatedSolid tsolid("test_tessellated");
TEST1(tsolid.GetLogical() != nullptr);
TEST1(tsolid.GetSolid() != nullptr);
// cube mesh //
TriangleMesh mesh;
mesh.AddPoint(Vector3f(0,0,0));
mesh.AddPoint(Vector3f(1,0,0));
mesh.AddPoint(Vector3f(0,1,0));
mesh.AddPoint(Vector3f(1,1,0));
mesh.AddPoint(Vector3f(0,0,1));
mesh.AddPoint(Vector3f(1,0,1));
mesh.AddPoint(Vector3f(0,1,1));
mesh.AddPoint(Vector3f(1,1,1));
// create triangles (consistent outward winding) //
// bottom (z=0)
mesh.AddTriangle(Vector3i(0,2,3));
mesh.AddTriangle(Vector3i(0,3,1));
// top (z=1)
mesh.AddTriangle(Vector3i(4,5,7));
mesh.AddTriangle(Vector3i(4,7,6));
// left (x=0)
mesh.AddTriangle(Vector3i(0,4,6));
mesh.AddTriangle(Vector3i(0,6,2));
// right (x=1)
mesh.AddTriangle(Vector3i(1,3,7));
mesh.AddTriangle(Vector3i(1,7,5));
// front (y=0)
mesh.AddTriangle(Vector3i(0,1,5));
mesh.AddTriangle(Vector3i(0,5,4));
// back (y=1)
mesh.AddTriangle(Vector3i(2,6,7));
mesh.AddTriangle(Vector3i(2,7,3));
tsolid.SetMesh(mesh);
TEST1(tsolid.GetSolid()->GetNumberOfFacets() == 12);
}
END_TESTING
}

View File

@@ -0,0 +1,37 @@
/*//////////////////////////////////////////////////////////////////////////////
// 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 <stdio.h>
#define BEGIN_TESTING(name) \
static int _fail = 0; \
printf("..:: Testing " #name " ::..\n");
#define TEST1(val) _fail += (val)==0
#define TEST0(val) _fail += (val)!=0
#define END_TESTING return _fail;

View File

@@ -39,12 +39,6 @@ class Hit {
Type m_DriftTime; Type m_DriftTime;
}; };
class HitMC { class HitMC {
public: public:
virtual Id_t GetChamber() = 0; virtual Id_t GetChamber() = 0;

View File

@@ -1,11 +0,0 @@
include $(top_srcdir)/Common.am
library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/ParticlePhysics/MuonTomography
library_include_HEADERS =
_PPMUTOM_SOURCES =
noinst_LTLIBRARIES = libmutomppmutom.la
libmutomppmutom_la_SOURCES = ${_PPMUTOM_SOURCES}

View File

@@ -23,29 +23,27 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CONTAINERBOX_H #ifndef U_CONTAINERBOX_H
#define U_CONTAINERBOX_H #define U_CONTAINERBOX_H
#include "Geometry.h" #include "Geometry.h"
#include "Core/Object.h"
#include "Math/Dense.h" #include "Math/Dense.h"
#include "Math/Transform.h" #include "Math/Transform.h"
#include <utility> #include <utility>
namespace uLib { namespace uLib {
/** /**
* @brief Represents an oriented bounding box (OBB) within a hierarchical transformation system. * @brief Represents an oriented bounding box (OBB) within a hierarchical
* transformation system.
* *
* ContainerBox inherits from AffineTransform, which defines its parent coordinate system. * ContainerBox inherits from AffineTransform, which defines its parent
* It contains an internal local transformation (m_LocalT) that defines the box's * coordinate system. It contains an internal local transformation (m_LocalT)
* specific origin and size relative to its own coordinate system. * that defines the box's specific origin and size relative to its own
* coordinate system.
*/ */
class ContainerBox : public AffineTransform { class ContainerBox : public AffineTransform, public Object {
typedef AffineTransform BaseClass; typedef AffineTransform BaseClass;
@@ -54,18 +52,23 @@ public:
* @brief Default constructor. * @brief Default constructor.
* Initializes the local transformation with this instance as its parent. * Initializes the local transformation with this instance as its parent.
*/ */
ContainerBox() : ContainerBox()
m_LocalT(this) // BaseClass is Parent of m_LocalTransform : m_LocalT(this) // BaseClass is Parent of m_LocalTransform
{} {}
/**
* @brief Constructor with size.
* @param size The size vector.
*/
ContainerBox(const Vector3f &size) : m_LocalT(this) { this->SetSize(size); }
/** /**
* @brief Copy constructor. * @brief Copy constructor.
* @param copy The ContainerBox instance to copy from. * @param copy The ContainerBox instance to copy from.
*/ */
ContainerBox(const ContainerBox &copy) : ContainerBox(const ContainerBox &copy)
m_LocalT(this), // BaseClass is Parent of m_LocalTransform : m_LocalT(this), // BaseClass is Parent of m_LocalTransform
AffineTransform(copy) AffineTransform(copy) {
{
this->SetOrigin(copy.GetOrigin()); this->SetOrigin(copy.GetOrigin());
this->SetSize(copy.GetSize()); this->SetSize(copy.GetSize());
} }
@@ -105,8 +108,9 @@ public:
* @param first Index of the first axis (0=X, 1=Y, 2=Z). * @param first Index of the first axis (0=X, 1=Y, 2=Z).
* @param second Index of the second axis (0=X, 1=Y, 2=Z). * @param second Index of the second axis (0=X, 1=Y, 2=Z).
*/ */
inline void FlipLocalAxes(int first, int second) inline void FlipLocalAxes(int first, int second) {
{ m_LocalT.FlipAxes(first,second); } m_LocalT.FlipAxes(first, second);
}
/** /**
* @brief Returns the world transformation matrix of the box's volume. * @brief Returns the world transformation matrix of the box's volume.
@@ -137,7 +141,7 @@ public:
* @return The transformed point in world space. * @return The transformed point in world space.
*/ */
inline Vector4f GetWorldPoint(const float x, const float y, const float z) { inline Vector4f GetWorldPoint(const float x, const float y, const float z) {
return this->GetWorldPoint(Vector4f(x,y,z,1)); return this->GetWorldPoint(Vector4f(x, y, z, 1));
} }
/** /**
@@ -157,7 +161,7 @@ public:
* @return The transformed point in box-local space. * @return The transformed point in box-local space.
*/ */
inline Vector4f GetLocalPoint(const float x, const float y, const float z) { inline Vector4f GetLocalPoint(const float x, const float y, const float z) {
return this->GetLocalPoint(Vector4f(x,y,z,1)); return this->GetLocalPoint(Vector4f(x, y, z, 1));
} }
/** Translate using transformation chain */ /** Translate using transformation chain */
@@ -169,14 +173,15 @@ public:
/** Scale using transformation chain */ /** Scale using transformation chain */
using BaseClass::Scale; using BaseClass::Scale;
signals:
// signal to emit when the box is updated //
void Updated() { ULIB_SIGNAL_EMIT(ContainerBox::Updated); }
private: private:
AffineTransform m_LocalT; AffineTransform m_LocalT;
}; };
} // namespace uLib
}
#endif // CONTAINERBOX_H #endif // CONTAINERBOX_H

View File

@@ -1,22 +1,22 @@
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h> #include <pybind11/eigen.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/stl_bind.h> #include <pybind11/stl_bind.h>
#include <pybind11/numpy.h> #include <pybind11/numpy.h>
#include "Math/Dense.h" #include "Math/Accumulator.h"
#include "Math/Transform.h"
#include "Math/Geometry.h"
#include "Math/ContainerBox.h" #include "Math/ContainerBox.h"
#include "Math/StructuredData.h" #include "Math/Dense.h"
#include "Math/StructuredGrid.h" #include "Math/Geometry.h"
#include "Math/Structured2DGrid.h" #include "Math/Structured2DGrid.h"
#include "Math/Structured4DGrid.h" #include "Math/Structured4DGrid.h"
#include "Math/StructuredData.h"
#include "Math/StructuredGrid.h"
#include "Math/Transform.h"
#include "Math/TriangleMesh.h" #include "Math/TriangleMesh.h"
#include "Math/VoxRaytracer.h"
#include "Math/Accumulator.h"
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "Math/VoxRaytracer.h"
namespace py = pybind11; namespace py = pybind11;
using namespace uLib; using namespace uLib;
@@ -45,7 +45,8 @@ void bind_eigen_type(py::module_ &m, const char *name) {
// Default constructor (zeros) // Default constructor (zeros)
m.def(name, []() -> MatrixType { m.def(name, []() -> MatrixType {
if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic) { if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic ||
MatrixType::ColsAtCompileTime == Eigen::Dynamic) {
return MatrixType(); // Empty dynamic matrix return MatrixType(); // Empty dynamic matrix
} else { } else {
return MatrixType::Zero(); // Zero static matrix return MatrixType::Zero(); // Zero static matrix
@@ -53,7 +54,8 @@ void bind_eigen_type(py::module_ &m, const char *name) {
}); });
// Specialized constructor for dynamic matrices // Specialized constructor for dynamic matrices
if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic) { if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic ||
MatrixType::ColsAtCompileTime == Eigen::Dynamic) {
m.def(name, [](int rows, int cols) -> MatrixType { m.def(name, [](int rows, int cols) -> MatrixType {
MatrixType mat; MatrixType mat;
mat.setZero(rows, cols); mat.setZero(rows, cols);
@@ -70,8 +72,12 @@ void bind_eigen_type(py::module_ &m, const char *name) {
mat(i) = l[i].cast<Scalar>(); mat(i) = l[i].cast<Scalar>();
} }
} else { } else {
int rows = MatrixType::RowsAtCompileTime == Eigen::Dynamic ? (int)std::sqrt(l.size()) : MatrixType::RowsAtCompileTime; int rows = MatrixType::RowsAtCompileTime == Eigen::Dynamic
int cols = MatrixType::ColsAtCompileTime == Eigen::Dynamic ? (int)std::sqrt(l.size()) : MatrixType::ColsAtCompileTime; ? (int)std::sqrt(l.size())
: MatrixType::RowsAtCompileTime;
int cols = MatrixType::ColsAtCompileTime == Eigen::Dynamic
? (int)std::sqrt(l.size())
: MatrixType::ColsAtCompileTime;
mat.setZero(rows, cols); mat.setZero(rows, cols);
for (size_t i = 0; i < (size_t)l.size(); ++i) { for (size_t i = 0; i < (size_t)l.size(); ++i) {
mat(i / cols, i % cols) = l[i].cast<Scalar>(); mat(i / cols, i % cols) = l[i].cast<Scalar>();
@@ -81,18 +87,21 @@ void bind_eigen_type(py::module_ &m, const char *name) {
}); });
// Initialize from py::array // Initialize from py::array
m.def(name, [](py::array_t<Scalar, py::array::c_style | py::array::forcecast> arr) -> MatrixType { m.def(name,
[](py::array_t<Scalar, py::array::c_style | py::array::forcecast> arr)
-> MatrixType {
auto buf = arr.request(); auto buf = arr.request();
MatrixType mat; MatrixType mat;
if constexpr (is_vector) { if constexpr (is_vector) {
mat.setZero(buf.size); mat.setZero(buf.size);
Scalar* ptr = static_cast<Scalar*>(buf.ptr); Scalar *ptr = static_cast<Scalar *>(buf.ptr);
for (ssize_t i = 0; i < buf.size; ++i) mat(i) = ptr[i]; for (ssize_t i = 0; i < buf.size; ++i)
mat(i) = ptr[i];
} else { } else {
int rows = buf.shape.size() > 0 ? (int)buf.shape[0] : 1; int rows = buf.shape.size() > 0 ? (int)buf.shape[0] : 1;
int cols = buf.shape.size() > 1 ? (int)buf.shape[1] : 1; int cols = buf.shape.size() > 1 ? (int)buf.shape[1] : 1;
mat.setZero(rows, cols); mat.setZero(rows, cols);
Scalar* ptr = static_cast<Scalar*>(buf.ptr); Scalar *ptr = static_cast<Scalar *>(buf.ptr);
for (int i = 0; i < rows; ++i) { for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) { for (int j = 0; j < cols; ++j) {
mat(i, j) = ptr[i * cols + j]; mat(i, j) = ptr[i * cols + j];
@@ -192,45 +201,68 @@ void init_math(py::module_ &m) {
py::bind_vector<uLib::Vector<Voxel>>(m, "Vector_Voxel") py::bind_vector<uLib::Vector<Voxel>>(m, "Vector_Voxel")
.def("MoveToVRAM", &uLib::Vector<Voxel>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Voxel>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Voxel>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Voxel>::MoveToRAM);
py::bind_vector<uLib::Vector<VoxRaytracer::RayData::Element>>(m, "Vector_VoxRaytracerRayDataElement") py::bind_vector<uLib::Vector<VoxRaytracer::RayData::Element>>(
.def("MoveToVRAM", &uLib::Vector<VoxRaytracer::RayData::Element>::MoveToVRAM) m, "Vector_VoxRaytracerRayDataElement")
.def("MoveToRAM", &uLib::Vector<VoxRaytracer::RayData::Element>::MoveToRAM); .def("MoveToVRAM",
&uLib::Vector<VoxRaytracer::RayData::Element>::MoveToVRAM)
.def("MoveToRAM",
&uLib::Vector<VoxRaytracer::RayData::Element>::MoveToRAM);
// 4. Accumulators // 4. Accumulators
py::class_<Accumulator_Mean<float>>(m, "Accumulator_Mean_f") py::class_<Accumulator_Mean<float>>(m, "Accumulator_Mean_f")
.def(py::init<>()) .def(py::init<>())
.def("AddPass", &Accumulator_Mean<float>::AddPass) .def("AddPass", &Accumulator_Mean<float>::AddPass)
.def("__call__", py::overload_cast<const float>(&Accumulator_Mean<float>::operator())) .def("__call__",
.def("__call__", py::overload_cast<>(&Accumulator_Mean<float>::operator(), py::const_)); py::overload_cast<const float>(&Accumulator_Mean<float>::operator()))
.def("__call__", py::overload_cast<>(&Accumulator_Mean<float>::operator(),
py::const_));
py::class_<Accumulator_Mean<double>>(m, "Accumulator_Mean_d") py::class_<Accumulator_Mean<double>>(m, "Accumulator_Mean_d")
.def(py::init<>()) .def(py::init<>())
.def("AddPass", &Accumulator_Mean<double>::AddPass) .def("AddPass", &Accumulator_Mean<double>::AddPass)
.def("__call__", py::overload_cast<const double>(&Accumulator_Mean<double>::operator())) .def("__call__", py::overload_cast<const double>(
.def("__call__", py::overload_cast<>(&Accumulator_Mean<double>::operator(), py::const_)); &Accumulator_Mean<double>::operator()))
.def("__call__", py::overload_cast<>(
&Accumulator_Mean<double>::operator(), py::const_));
py::class_<Accumulator_ABTrim<float>>(m, "Accumulator_ABTrim_f") py::class_<Accumulator_ABTrim<float>>(m, "Accumulator_ABTrim_f")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<float>::SetABTrim) .def("SetABTrim", &Accumulator_ABTrim<float>::SetABTrim)
.def("__iadd__", [](Accumulator_ABTrim<float> &self, float val) { self += val; return &self; }) .def("__iadd__",
[](Accumulator_ABTrim<float> &self, float val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABTrim<float>::operator()); .def("__call__", &Accumulator_ABTrim<float>::operator());
py::class_<Accumulator_ABTrim<double>>(m, "Accumulator_ABTrim_d") py::class_<Accumulator_ABTrim<double>>(m, "Accumulator_ABTrim_d")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<double>::SetABTrim) .def("SetABTrim", &Accumulator_ABTrim<double>::SetABTrim)
.def("__iadd__", [](Accumulator_ABTrim<double> &self, double val) { self += val; return &self; }) .def("__iadd__",
[](Accumulator_ABTrim<double> &self, double val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABTrim<double>::operator()); .def("__call__", &Accumulator_ABTrim<double>::operator());
py::class_<Accumulator_ABClip<float>>(m, "Accumulator_ABClip_f") py::class_<Accumulator_ABClip<float>>(m, "Accumulator_ABClip_f")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<float>::SetABTrim) .def("SetABTrim", &Accumulator_ABClip<float>::SetABTrim)
.def("__iadd__", [](Accumulator_ABClip<float> &self, float val) { self += val; return &self; }) .def("__iadd__",
[](Accumulator_ABClip<float> &self, float val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABClip<float>::operator()); .def("__call__", &Accumulator_ABClip<float>::operator());
py::class_<Accumulator_ABClip<double>>(m, "Accumulator_ABClip_d") py::class_<Accumulator_ABClip<double>>(m, "Accumulator_ABClip_d")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<double>::SetABTrim) .def("SetABTrim", &Accumulator_ABClip<double>::SetABTrim)
.def("__iadd__", [](Accumulator_ABClip<double> &self, double val) { self += val; return &self; }) .def("__iadd__",
[](Accumulator_ABClip<double> &self, double val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABClip<double>::operator()); .def("__call__", &Accumulator_ABClip<double>::operator());
// 5. Core Math Structures // 5. Core Math Structures
@@ -243,24 +275,42 @@ void init_math(py::module_ &m) {
.def("Scale", &AffineTransform::Scale) .def("Scale", &AffineTransform::Scale)
.def("SetRotation", &AffineTransform::SetRotation) .def("SetRotation", &AffineTransform::SetRotation)
.def("GetRotation", &AffineTransform::GetRotation) .def("GetRotation", &AffineTransform::GetRotation)
.def("Rotate", &AffineTransform::Rotate) .def("Rotate",
py::overload_cast<const Matrix3f>(&AffineTransform::Rotate))
.def("Rotate",
py::overload_cast<float, Vector3f>(&AffineTransform::Rotate))
.def("Rotate", py::overload_cast<Vector3f>(&AffineTransform::Rotate))
.def("EulerYZYRotate", &AffineTransform::EulerYZYRotate) .def("EulerYZYRotate", &AffineTransform::EulerYZYRotate)
.def("FlipAxes", &AffineTransform::FlipAxes); .def("FlipAxes", &AffineTransform::FlipAxes);
py::class_<Geometry, AffineTransform>(m, "Geometry") py::class_<Geometry, AffineTransform>(m, "Geometry")
.def(py::init<>()) .def(py::init<>())
.def("GetWorldPoint", &Geometry::GetWorldPoint) .def("GetWorldPoint", py::overload_cast<const Vector4f>(
.def("GetLocalPoint", &Geometry::GetLocalPoint); &Geometry::GetWorldPoint, py::const_))
.def("GetWorldPoint",
py::overload_cast<float, float, float>(&Geometry::GetWorldPoint))
.def("GetLocalPoint", py::overload_cast<const Vector4f>(
&Geometry::GetLocalPoint, py::const_))
.def("GetLocalPoint",
py::overload_cast<float, float, float>(&Geometry::GetLocalPoint));
py::class_<ContainerBox, AffineTransform>(m, "ContainerBox") py::class_<ContainerBox, AffineTransform, Object>(m, "ContainerBox")
.def(py::init<>()) .def(py::init<>())
.def("SetOrigin", &ContainerBox::SetOrigin) .def("SetOrigin", &ContainerBox::SetOrigin)
.def("GetOrigin", &ContainerBox::GetOrigin) .def("GetOrigin", &ContainerBox::GetOrigin)
.def("SetSize", &ContainerBox::SetSize) .def("SetSize", &ContainerBox::SetSize)
.def("GetSize", &ContainerBox::GetSize) .def("GetSize", &ContainerBox::GetSize)
.def("GetLocalMatrix", &ContainerBox::GetLocalMatrix)
.def("GetWorldMatrix", &ContainerBox::GetWorldMatrix) .def("GetWorldMatrix", &ContainerBox::GetWorldMatrix)
.def("GetWorldPoint", &ContainerBox::GetWorldPoint) .def("GetWorldPoint", py::overload_cast<const Vector4f &>(
.def("GetLocalPoint", &ContainerBox::GetLocalPoint); &ContainerBox::GetWorldPoint, py::const_))
.def("GetWorldPoint",
py::overload_cast<float, float, float>(&ContainerBox::GetWorldPoint))
.def("GetLocalPoint", py::overload_cast<const Vector4f &>(
&ContainerBox::GetLocalPoint, py::const_))
.def("GetLocalPoint",
py::overload_cast<float, float, float>(&ContainerBox::GetLocalPoint))
.def("FlipLocalAxes", &ContainerBox::FlipLocalAxes);
py::enum_<StructuredData::_Order>(m, "StructuredDataOrder") py::enum_<StructuredData::_Order>(m, "StructuredDataOrder")
.value("CustomOrder", StructuredData::CustomOrder) .value("CustomOrder", StructuredData::CustomOrder)
@@ -330,10 +380,14 @@ void init_math(py::module_ &m) {
.def_readwrite("Count", &Voxel::Count); .def_readwrite("Count", &Voxel::Count);
py::class_<Abstract::VoxImage, StructuredGrid>(m, "AbstractVoxImage") py::class_<Abstract::VoxImage, StructuredGrid>(m, "AbstractVoxImage")
.def("GetValue", py::overload_cast<const Vector3i &>(&Abstract::VoxImage::GetValue, py::const_)) .def("GetValue", py::overload_cast<const Vector3i &>(
.def("GetValue", py::overload_cast<const int>(&Abstract::VoxImage::GetValue, py::const_)) &Abstract::VoxImage::GetValue, py::const_))
.def("SetValue", py::overload_cast<const Vector3i &, float>(&Abstract::VoxImage::SetValue)) .def("GetValue", py::overload_cast<const int>(
.def("SetValue", py::overload_cast<const int, float>(&Abstract::VoxImage::SetValue)) &Abstract::VoxImage::GetValue, py::const_))
.def("SetValue", py::overload_cast<const Vector3i &, float>(
&Abstract::VoxImage::SetValue))
.def("SetValue",
py::overload_cast<const int, float>(&Abstract::VoxImage::SetValue))
.def("ExportToVtk", &Abstract::VoxImage::ExportToVtk) .def("ExportToVtk", &Abstract::VoxImage::ExportToVtk)
.def("ExportToVti", &Abstract::VoxImage::ExportToVti) .def("ExportToVti", &Abstract::VoxImage::ExportToVti)
.def("ImportFromVtk", &Abstract::VoxImage::ImportFromVtk) .def("ImportFromVtk", &Abstract::VoxImage::ImportFromVtk)
@@ -342,24 +396,40 @@ void init_math(py::module_ &m) {
py::class_<VoxImage<Voxel>, Abstract::VoxImage>(m, "VoxImage") py::class_<VoxImage<Voxel>, Abstract::VoxImage>(m, "VoxImage")
.def(py::init<>()) .def(py::init<>())
.def(py::init<const Vector3i &>()) .def(py::init<const Vector3i &>())
.def("Data", &VoxImage<Voxel>::Data, py::return_value_policy::reference_internal) .def("Data", &VoxImage<Voxel>::Data,
py::return_value_policy::reference_internal)
.def("InitVoxels", &VoxImage<Voxel>::InitVoxels) .def("InitVoxels", &VoxImage<Voxel>::InitVoxels)
.def("Abs", &VoxImage<Voxel>::Abs) .def("Abs", &VoxImage<Voxel>::Abs)
.def("clipImage", py::overload_cast<const Vector3i, const Vector3i>(&VoxImage<Voxel>::clipImage, py::const_)) .def("clipImage", py::overload_cast<const Vector3i, const Vector3i>(
.def("clipImage", py::overload_cast<const HPoint3f, const HPoint3f>(&VoxImage<Voxel>::clipImage, py::const_)) &VoxImage<Voxel>::clipImage, py::const_))
.def("clipImage", py::overload_cast<const float>(&VoxImage<Voxel>::clipImage, py::const_)) .def("clipImage", py::overload_cast<const HPoint3f, const HPoint3f>(
.def("maskImage", py::overload_cast<const HPoint3f, const HPoint3f, float>(&VoxImage<Voxel>::maskImage, py::const_)) &VoxImage<Voxel>::clipImage, py::const_))
.def("maskImage", py::overload_cast<const float, float, float>(&VoxImage<Voxel>::maskImage, py::const_), py::arg("threshold"), py::arg("belowValue") = 0, py::arg("aboveValue") = 0) .def("clipImage", py::overload_cast<const float>(
.def("fixVoxels", py::overload_cast<const float, float>(&VoxImage<Voxel>::fixVoxels, py::const_)) &VoxImage<Voxel>::clipImage, py::const_))
.def("__getitem__", py::overload_cast<unsigned int>(&VoxImage<Voxel>::operator[])) .def("maskImage",
.def("__getitem__", py::overload_cast<const Vector3i &>(&VoxImage<Voxel>::operator[])); py::overload_cast<const HPoint3f, const HPoint3f, float>(
&VoxImage<Voxel>::maskImage, py::const_))
.def("maskImage",
py::overload_cast<const float, float, float>(
&VoxImage<Voxel>::maskImage, py::const_),
py::arg("threshold"), py::arg("belowValue") = 0,
py::arg("aboveValue") = 0)
.def("fixVoxels", py::overload_cast<const float, float>(
&VoxImage<Voxel>::fixVoxels, py::const_))
.def("__getitem__",
py::overload_cast<unsigned int>(&VoxImage<Voxel>::operator[]))
.def("__getitem__",
py::overload_cast<const Vector3i &>(&VoxImage<Voxel>::operator[]));
py::class_<TriangleMesh>(m, "TriangleMesh") py::class_<TriangleMesh>(m, "TriangleMesh")
.def(py::init<>()) .def(py::init<>())
.def("AddPoint", &TriangleMesh::AddPoint) .def("AddPoint", &TriangleMesh::AddPoint)
.def("AddTriangle", py::overload_cast<const Vector3i &>(&TriangleMesh::AddTriangle)) .def("AddTriangle",
.def("Points", &TriangleMesh::Points, py::return_value_policy::reference_internal) py::overload_cast<const Vector3i &>(&TriangleMesh::AddTriangle))
.def("Triangles", &TriangleMesh::Triangles, py::return_value_policy::reference_internal); .def("Points", &TriangleMesh::Points,
py::return_value_policy::reference_internal)
.def("Triangles", &TriangleMesh::Triangles,
py::return_value_policy::reference_internal);
py::class_<VoxRaytracer::RayData::Element>(m, "VoxRaytracerRayDataElement") py::class_<VoxRaytracer::RayData::Element>(m, "VoxRaytracerRayDataElement")
.def(py::init<>()) .def(py::init<>())
@@ -369,7 +439,8 @@ void init_math(py::module_ &m) {
py::class_<VoxRaytracer::RayData>(m, "VoxRaytracerRayData") py::class_<VoxRaytracer::RayData>(m, "VoxRaytracerRayData")
.def(py::init<>()) .def(py::init<>())
.def("AppendRay", &VoxRaytracer::RayData::AppendRay) .def("AppendRay", &VoxRaytracer::RayData::AppendRay)
.def("Data", py::overload_cast<>(&VoxRaytracer::RayData::Data), py::return_value_policy::reference_internal) .def("Data", py::overload_cast<>(&VoxRaytracer::RayData::Data),
py::return_value_policy::reference_internal)
.def("Count", &VoxRaytracer::RayData::Count) .def("Count", &VoxRaytracer::RayData::Count)
.def("TotalLength", &VoxRaytracer::RayData::TotalLength) .def("TotalLength", &VoxRaytracer::RayData::TotalLength)
.def("SetCount", &VoxRaytracer::RayData::SetCount) .def("SetCount", &VoxRaytracer::RayData::SetCount)
@@ -377,8 +448,8 @@ void init_math(py::module_ &m) {
py::class_<VoxRaytracer>(m, "VoxRaytracer") py::class_<VoxRaytracer>(m, "VoxRaytracer")
.def(py::init<StructuredGrid &>(), py::keep_alive<1, 2>()) .def(py::init<StructuredGrid &>(), py::keep_alive<1, 2>())
.def("GetImage", &VoxRaytracer::GetImage, py::return_value_policy::reference_internal) .def("GetImage", &VoxRaytracer::GetImage,
py::return_value_policy::reference_internal)
.def("TraceLine", &VoxRaytracer::TraceLine) .def("TraceLine", &VoxRaytracer::TraceLine)
.def("TraceBetweenPoints", &VoxRaytracer::TraceBetweenPoints); .def("TraceBetweenPoints", &VoxRaytracer::TraceBetweenPoints);
} }

View File

@@ -102,6 +102,7 @@ void vtkDetectorChamber::SetTransform(vtkTransform *t) {
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
transform(i, j) = vmat->GetElement(i, j); transform(i, j) = vmat->GetElement(i, j);
this->GetContent()->SetMatrix(transform); this->GetContent()->SetMatrix(transform);
this->GetContent()->Updated(); // emit signal
this->Update(); this->Update();
} }

View File

@@ -72,8 +72,7 @@ void vtkContainerBox::Update() {
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
vmat->SetElement(i, j, transform(i, j)); vmat->SetElement(i, j, transform(i, j));
std::cout << "transform: " << transform << std::endl; // std::cout << "transform: " << transform << std::endl;
// m_RelativeTransform->SetMatrix(vmat); // m_RelativeTransform->SetMatrix(vmat);
// m_RelativeTransform->Update(); // m_RelativeTransform->Update();