Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kill not interacting particles actor #376

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions core/opengate_core/opengate_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,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 @@ -561,6 +563,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,75 @@
/* --------------------------------------------------
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 "G4LogicalVolumeStore.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4ios.hh"
#include "GateHelpers.h"
#include "GateHelpersDict.h"

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 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();
}
}

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

fIsFirstStep = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* --------------------------------------------------
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,22 @@
/* --------------------------------------------------
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 @@ -19,6 +19,7 @@
KillActor,
BremSplittingActor,
ComptSplittingActor,
KillNonInteractingParticleActor,
)
from .dynamicactors import DynamicGeometryActor
from ..utility import make_builders
Expand Down Expand Up @@ -46,6 +47,7 @@
KillActor,
BremSplittingActor,
ComptSplittingActor,
KillNonInteractingParticleActor,
DynamicGeometryActor,
}
actor_builders = make_builders(actor_type_names)
31 changes: 31 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 @@ -477,3 +478,33 @@ def set_default_user_info(user_info):
def __init__(self, user_info):
ActorBase.__init__(self, user_info)
g4.GateBOptrBremSplittingActor.__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 @@ -1034,6 +1034,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):
log.setLevel(verbose_level)
Expand Down
Loading