Could not get the results

Please fill out the following information to help in answering your question, and also see tips for posting code snippets. If you don’t provide this information it will take more time to help with your problem!

_Geant4 Version:_geant4-v11.2.0
_Operating System:_win11
_Compiler/Version:_Visual Studio Version 17.3.5
_CMake Version:_cmake-3.28.1


Hello everyone,

I am currently trying to learn Geant4 and to do this I am studying on a project that bombards the target with gamma rays. I’m trying to find the difference in light intensity between these rays after they hit the target. I do not know what should I have in this project. When I command /run/beamOn 10 simulation suddenly closing and gives no results. Then after closing the window I get

Could not convert to integer: 3221226505. Path ‘exitCode’.
Value was either too large or too small for an In32.

The code that I updated B1 example a little, looks fine but I guess there should be “Track” or “Detector”. In addition the B1 Example code works totally fine.
Plus I use geant4_pybind.

import cmath
from os import environ
from geant4_pybind import *

import sys
import math


class DetectorConstruction(G4VUserDetectorConstruction): 
    def __init__(self):
        super().__init__()
        self.fScoringVolume = None
        
    def DefineMaterials(self):
        nist = G4NistManager.Instance()

        isotopes = False
        C = nist.FindOrBuildElement("C", isotopes)
        H = nist.FindOrBuildElement("H", isotopes)
        O = nist.FindOrBuildElement("O", isotopes)
        S = nist.FindOrBuildElement("S", isotopes)

        self.PSU = G4Material("Polysulfone", 1.183*g/cm3)
        self.PSU.AddElement(C, 6)
        self.PSU.AddElement(O, 2)
        self.PSU.AddElement(H, 4)
        self.PSU.AddElement(S, 1)
        

    def Construct(self):
        nist = G4NistManager.Instance()
        env_sizeXY = 80*cm
        env_sizeZ = 80*cm
        env_mat = nist.FindOrBuildMaterial("G4_AIR")
        targetMaterial = nist.FindOrBuildMaterial("Polysulfone")

        checkOverlaps = True

        #WORLD
        world_sizeXY = 1.2*env_sizeXY
        world_sizeZ = 1.2*env_sizeZ
        world_mat = nist.FindOrBuildMaterial("G4_AIR")

        solidWorld = G4Box("World", 0.5*world_sizeXY, 0.5 *
                           world_sizeXY, 0.5*world_sizeZ)
        logicWorld = G4LogicalVolume(solidWorld, world_mat, "World")

        physWorld = G4PVPlacement(None,              # no rotation
                                  G4ThreeVector(),   # at (0,0,0)
                                  logicWorld,        # its logical volume
                                  "World",           # its name
                                  None,              # its mother  volume
                                  False,             # no boolean operation
                                  0,                 # copy number
                                  checkOverlaps)     # overlaps checking

        
        #ENVELOPE
        solidEnv = G4Box("Envelope", 0.5*env_sizeXY,
                         0.5*env_sizeXY, 0.5*env_sizeZ)

        logicEnv = G4LogicalVolume(solidEnv,    # its solid
                                   env_mat,     # its material
                                   "Envelope")  # its name

        G4PVPlacement(None,              # no rotation
                      G4ThreeVector(),   # at (0,0,0)
                      logicEnv,          # its logical volume
                      "Envelope",        # its name
                      logicWorld,        # its mother  volume
                      True,              # no boolean operation
                      0,                 # copy number
                      checkOverlaps)     # overlaps checking
        

        
        targetExample = G4Box("Target", 1.0*cm , 5.0*cm, 5.0*cm )

        # Create logical volume
        logic_target = G4LogicalVolume(targetExample, targetMaterial, "Target")

        # Place the cylinder in the world volume
        position = G4ThreeVector(5.0*cm, 0, 0)
        rotation = G4RotationMatrix()
        physical_target = G4PVPlacement(None, position, logic_target, "Target", logicEnv, False, 0, checkOverlaps)

        self.fScoringVolume = logic_target

        return physWorld

class RunAction(G4UserRunAction):
    def __init__(self):
        super().__init__()
        milligray = 1.e-3*gray
        microgray = 1.e-6*gray
        nanogray = 1.e-9*gray
        picogray = 1.e-12*gray

        G4UnitDefinition("milligray", "milliGy", "Dose", milligray)
        G4UnitDefinition("microgray", "microGy", "Dose", microgray)
        G4UnitDefinition("nanogray", "nanoGy", "Dose", nanogray)
        G4UnitDefinition("picogray", "picoGy", "Dose", picogray)

        self.edep = G4Accumulable(0)
        self.edep2 = G4Accumulable(0)

        accumulableManager = G4AccumulableManager.Instance()
        accumulableManager.RegisterAccumulable(self.edep)
        accumulableManager.RegisterAccumulable(self.edep2)

    def BeginOfRunAction(self, aRun):
        G4RunManager.GetRunManager().SetRandomNumberStore(False)

        accumulableManager = G4AccumulableManager.Instance()
        accumulableManager.Reset()

    def EndOfRunAction(self, aRun):
        nofEvents = aRun.GetNumberOfEvent()
        if nofEvents == 0:
            return

        # Merge accumulables
        accumulableManager = G4AccumulableManager.Instance()
        accumulableManager.Merge()

        edep = self.edep.GetValue()
        edep2 = self.edep2.GetValue()

        # Compute dose = total energy deposit in a run and its variance
        rms = edep2 - edep*edep/nofEvents
        if rms > 0:
            rms = math.sqrt(rms)
        else:
            rms = 0

        detectorConstruction = G4RunManager.GetRunManager().GetUserDetectorConstruction()
        mass = detectorConstruction.fScoringVolume.GetMass()
        dose = edep/mass
        rmsDose = rms/mass

        generatorAction = G4RunManager.GetRunManager().GetUserPrimaryGeneratorAction()
        runCondition = ""
        if generatorAction != None and isinstance(generatorAction, B1PrimaryGeneratorAction):
            particleGun = generatorAction.fParticleGun
            runCondition += particleGun.GetParticleDefinition().GetParticleName() + "(s)"
            runCondition += " of "
            particleEnergy = particleGun.GetParticleEnergy()
            runCondition += "{:.5g}".format(G4BestUnit(particleEnergy, "Energy"))

        if self.IsMaster():
            print("--------------------End of Global Run-----------------------")
        else:
            print("--------------------End of Local Run------------------------")

        print(" The run consists of", nofEvents, runCondition)
        print(" Cumulated dose per run, in scoring volume: ", end="")
        print("{:.5f} rms = {:.5f}".format(G4BestUnit(dose, "Dose"), G4BestUnit(rmsDose, "Dose")))
        print("------------------------------------------------------------")
        print("")

    def AddEdep(self, edep):
        self.edep += edep
        self.edep2 += edep*edep

class EventAction(G4UserEventAction):

    def __init__(self, runAction):
        super().__init__()
        self.fRunAction = runAction

    def BeginOfEventAction(self, anEvent):
        self.fEdep = 0 

    def EndOfEventAction(self, anEvent):
        self.ffRunAction.AddEdep(self.fEdep)

    def AddEdep(self, edep):
        self.fEdep += edep


class SteppingAction(G4UserSteppingAction):

    def __init__(self, eventAction):
        super().__init__()
        self.fEventAction = eventAction
        self.fScoringVolume = None

    def UserSteppingAction(self, aStep):
        if self.fScoringVolume == None:
            detectorConstruction = G4RunManager.GetRunManager().GetUserDetectorConstruction()
            self.fScoringVolume = detectorConstruction.fScoringVolume

        volume = aStep.GetPreStepPoint().GetTouchable().GetVolume().GetLogicalVolume()

        # check if we are in scoring volume
        if volume != self.fScoringVolume:
            return

        # collect energy deposited in this step
        edepStep = aStep.GetTotalEnergyDeposit()
        self.fEventAction.AddEdep(edepStep)

class PrimaryGeneratorAction(G4VUserPrimaryGeneratorAction):

    def __init__(self):
        super().__init__()
        self.fEnvelopeBox = None
        self.fParticleGun = G4ParticleGun(1)

        # default particle kinematic  energy range between 0.1 and 20 MeV
        particleTable = G4ParticleTable.GetParticleTable()
        particle = particleTable.FindParticle("gamma")
        self.fParticleGun.SetParticleDefinition(particle)
        self.fParticleGun.SetParticleMomentumDirection(G4ThreeVector(1, 0, 0))
        self.fParticleGun.SetParticleEnergy(0.1*MeV)

    def GeneratePrimaries(self, anEvent):
        # this function is called at the begining of each event

        # In order to avoid dependence of PrimaryGeneratorAction
        # on DetectorConstruction class we get Envelope volume
        # from G4LogicalVolumeStore.
        envSizeXY = 0
        envSizeZ = 0
        if self.fEnvelopeBox == None:
            envLV = G4LogicalVolumeStore.GetInstance().GetVolume("Envelope")
            if envLV != None:
                self.fEnvelopeBox = envLV.GetSolid()

        if self.fEnvelopeBox != None:
            envSizeXY = self.fEnvelopeBox.GetXHalfLength()*2
            envSizeZ = self.fEnvelopeBox.GetZHalfLength()*2
        else:
            msg = "Envelope volume of box shape not found.\n"
            msg += "Perhaps you have changed geometry.\n"
            msg += "The gun will be place at the center."
            G4Exception("B1PrimaryGeneratorAction::GeneratePrimaries()",
                        "MyCode0002", G4ExceptionSeverity.JustWarning, msg)

        size = 0.8
        x0 = size * envSizeXY * (G4UniformRand()-0.5)
        y0 = size * envSizeXY * (G4UniformRand()-0.5)
        z0 = -0.5 * envSizeZ

        self.fParticleGun.SetParticlePosition(G4ThreeVector(x0, y0, z0))
        self.fParticleGun.GeneratePrimaryVertex(anEvent)

class ActionInitialization(G4VUserActionInitialization):

    def BuildForMaster(self):
        self.SetUserAction(B1RunAction())

    def Build(self):
        self.SetUserAction(PrimaryGeneratorAction())

        runAction = RunAction()
        self.SetUserAction(runAction)

        eventAction = EventAction(runAction)
        self.SetUserAction(eventAction)

        self.SetUserAction(SteppingAction(eventAction))

ui = None
if len(sys.argv) == 1:
    ui = G4UIExecutive(len(sys.argv), sys.argv)

# Optionally: choose a different Random engine...
# G4Random.setTheEngine(MTwistEngine())

runManager = G4RunManagerFactory.CreateRunManager(G4RunManagerType.Serial)

runManager.SetUserInitialization(DetectorConstruction())

# Physics list
physicsList = QBBC()
physicsList.SetVerboseLevel(1)

runManager.SetUserInitialization(physicsList)

# User action initialization
runManager.SetUserInitialization(ActionInitialization())

visManager = G4VisExecutive()
# G4VisExecutive can take a verbosity argument - see /vis/verbose guidance.
# visManager = G4VisExecutive("Quiet")
visManager.Initialize()

# Get the User Interface manager
UImanager = G4UImanager.GetUIpointer()

# # Process macro or start UI session
if ui == None:
    # batch mode
    command = "/control/execute "
    fileName = sys.argv[1]
    UImanager.ApplyCommand(command+fileName)
else:
    # interactive mode
    UImanager.ApplyCommand("/control/execute init_vis.mac")
    ui.SessionStart()

I do not know, should I have “Envelope”? How to collect results?

It may be better to address this to the geant4_pybind Issue tracker. Whilst we can offer some general guidance, this is a third party project so we can’t offer support like we can for the C++ interface.

As far as I know, geant4_pybind should offer all the core interfaces needed (but see the caveat in its README), so the Application Developer Guide is still relevant here, albeit you’ll need to translate from C++ to Python.

1 Like