Skip to content

Commit

Permalink
Development of an actor which kill a track if this one passes through…
Browse files Browse the repository at this point in the history
…t the actor volume without any interaction
  • Loading branch information
majacquet committed Mar 19, 2024
1 parent 75ff0ba commit dd00658
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/opengate_core/opengate_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ void init_GateARFTrainingDatasetActor(py::module &m);

void init_GateKillActor(py::module &);

void init_GateKillNonInteractingParticleActor(py::module &);

void init_itk_image(py::module &);

void init_GateImageNestedParameterisation(py::module &);
Expand Down Expand Up @@ -493,6 +495,7 @@ PYBIND11_MODULE(opengate_core, m) {
init_GateARFActor(m);
init_GateARFTrainingDatasetActor(m);
init_GateKillActor(m);
init_GateKillNonInteractingParticleActor(m);
init_GateDigiAttributeManager(m);
init_GateVDigiAttribute(m);
init_GateExceptionHandler(m);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* --------------------------------------------------
Copyright (C): OpenGATE Collaboration
This software is distributed under the terms
of the GNU Lesser General Public Licence (LGPL)
See LICENSE.md for further details
------------------------------------ -------------- */

#include "GateKillNonInteractingParticleActor.h"
#include "G4ios.hh"
#include "GateHelpers.h"
#include "GateHelpersDict.h"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"


GateKillNonInteractingParticleActor::GateKillNonInteractingParticleActor(py::dict &user_info)
: GateVActor(user_info, false) {
fActions.insert("StartSimulationAction");
fActions.insert("SteppingAction");
fActions.insert("PreUserTrackingAction");
}




void GateKillNonInteractingParticleActor::ActorInitialize() {}

void GateKillNonInteractingParticleActor::StartSimulationAction() {
fNbOfKilledParticles = 0;
}


void GateKillNonInteractingParticleActor::PreUserTrackingAction(const G4Track* track) {
fIsFirstStep = true;
fKineticEnergyAtTheEntrance = 0;
ftrackIDAtTheEntrance = 0;
fPassedByTheMotherVolume = false;

}

void GateKillNonInteractingParticleActor::SteppingAction(G4Step *step) {

G4String logicalVolumeNamePostStep = step->GetPostStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetName();
if ((fPassedByTheMotherVolume) && (step->GetPostStepPoint()->GetStepStatus() == 1)){
if (std::find(fListOfVolumeAncestor.begin(), fListOfVolumeAncestor.end(),logicalVolumeNamePostStep ) !=fListOfVolumeAncestor.end()){
if ((step->GetTrack()->GetTrackID() == ftrackIDAtTheEntrance) && (step->GetPostStepPoint()->GetKineticEnergy() == fKineticEnergyAtTheEntrance)){
auto track = step->GetTrack();
track->SetTrackStatus(fStopAndKill);
fNbOfKilledParticles++;
}
}
}

G4String logNameMotherVolume = G4LogicalVolumeStore::GetInstance()->GetVolume(fMotherVolumeName)->GetName();
G4String physicalVolumeNamePreStep = step->GetPreStepPoint()->GetPhysicalVolume()->GetName();
if ((step->GetTrack()->GetLogicalVolumeAtVertex()->GetName() != logNameMotherVolume) && (fIsFirstStep)){
if ((fPassedByTheMotherVolume == false) && (physicalVolumeNamePreStep == fMotherVolumeName) && (step->GetPreStepPoint()->GetStepStatus() == 1)){
fPassedByTheMotherVolume =true;
fKineticEnergyAtTheEntrance = step->GetPreStepPoint()->GetKineticEnergy();
ftrackIDAtTheEntrance = step->GetTrack()->GetTrackID();
}
}

fIsFirstStep = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* --------------------------------------------------
Copyright (C): OpenGATE Collaboration
This software is distributed under the terms
of the GNU Lesser General Public Licence (LGPL)
See LICENSE.md for further details
-------------------------------------------------- */

#ifndef GateKillNonInteractingParticleActor_h
#define GateKillNonInteractingParticleActor_h

#include "G4Cache.hh"
#include "GateVActor.h"
#include <pybind11/stl.h>

namespace py = pybind11;

class GateKillNonInteractingParticleActor : public GateVActor {

public:
// Constructor
GateKillNonInteractingParticleActor(py::dict &user_info);

void ActorInitialize() override;

void StartSimulationAction() override;

// Main function called every step in attached volume
void SteppingAction(G4Step *) override;

void PreUserTrackingAction(const G4Track*) override;

std::vector<G4String> fParticlesTypeToKill;
G4bool fPassedByTheMotherVolume= false;
G4double fKineticEnergyAtTheEntrance = 0;
G4int ftrackIDAtTheEntrance = 0;
G4bool fIsFirstStep = true;
std::vector<std::string> fListOfVolumeAncestor;


long fNbOfKilledParticles{};
};

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* --------------------------------------------------
Copyright (C): OpenGATE Collaboration
This software is distributed under the terms
of the GNU Lesser General Public Licence (LGPL)
See LICENSE.md for further details
-------------------------------------------------- */

#include <pybind11/pybind11.h>

namespace py = pybind11;

#include "GateKillNonInteractingParticleActor.h"

void init_GateKillNonInteractingParticleActor(py::module &m) {
py::class_<GateKillNonInteractingParticleActor, std::unique_ptr<GateKillNonInteractingParticleActor, py::nodelete>,
GateVActor>(m, "GateKillNonInteractingParticleActor")
.def_readwrite("fListOfVolumeAncestor", &GateKillNonInteractingParticleActor::fListOfVolumeAncestor)
.def(py::init<py::dict &>());
}
2 changes: 2 additions & 0 deletions opengate/actors/actorbuilders.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
SourceInfoActor,
TestActor,
KillActor,
KillNonInteractingParticleActor,
)
from .dynamicactors import DynamicGeometryActor
from ..utility import make_builders
Expand All @@ -42,6 +43,7 @@
ARFTrainingDatasetActor,
TestActor,
KillActor,
KillNonInteractingParticleActor,
DynamicGeometryActor,
}
actor_builders = make_builders(actor_type_names)
36 changes: 36 additions & 0 deletions opengate/actors/miscactors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import numpy as np
import time
import platform
from anytree import Node, RenderTree
import opengate_core as g4
from .base import ActorBase
from ..exception import fatal
Expand Down Expand Up @@ -427,3 +428,38 @@ def set_default_user_info(user_info):
def __init__(self, user_info):
ActorBase.__init__(self, user_info)
g4.GateKillActor.__init__(self, user_info.__dict__)


class KillNonInteractingParticleActor(g4.GateKillNonInteractingParticleActor, ActorBase):
type_name = "KillNonInteractingParticleActor"

def set_default_user_info(user_info):
ActorBase.set_default_user_info(user_info)
user_info.list_of_volume_name = []


def __init__(self, user_info):
ActorBase.__init__(self, user_info)
g4.GateKillNonInteractingParticleActor.__init__(self, user_info.__dict__)
self.list_of_volume_name = user_info.list_of_volume_name
self.user_info.mother = user_info.mother


def initialize(self, volume_engine=None):

super().initialize(volume_engine)
volume_tree = self.simulation.volume_manager.get_volume_tree()
dico_of_volume_tree = {}
for pre, _, node in RenderTree(volume_tree):
dico_of_volume_tree[str(node.name)] = node
volume_name = self.user_info.mother
while volume_name != 'world':
node = dico_of_volume_tree[volume_name]
volume_name = node.mother
self.list_of_volume_name.append(volume_name)
self.fListOfVolumeAncestor = self.list_of_volume_name





3 changes: 3 additions & 0 deletions opengate/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,9 @@ def dump_volume_types(self):

def dump_material_database_names(self):
return list(self.material_database.filenames)

def get_volume_tree(self):
return (self.volume_tree_root)


def setter_hook_verbose_level(self, verbose_level):
Expand Down
Loading

0 comments on commit dd00658

Please sign in to comment.