Change materials properties during run

I am looking to change the absorption length of optical photons based on interaction depth of a particle that produces scintillation photons.

My first thought is to create a function that can be called from stepping action to set a property table for a material under certain conditions, and to give it a value that can be used to calculate absorption length. Would changing the propertytable like this even effect the Logical/Physical objects already placed? Will I have to build and place a new logical and physical object each time I change this value?

If there is an easier way of doing this I am open to suggestions.


You can’t do changes like that during the run: part of setting up the geometry and the physics is pre-computing stuff based on the configured geometry, so that tracking can be faster.


It seems like the absorption length should be fairly simple… It will affect the probability of absorption of an optical photon but the length traveled in the material depends on interaction depth. I am imaging just changing a value before optical photons are generated.

I know there are some macros that allow for changing geometry during the run, but they involved actually deleting and rebuilding the geometry.


when you write “during run”, do you mean while the application is running, or during what is called “run” in geant4 jargon? do these macros change the geometry while /run/beamOn N is still working, or between two consecutive /run/beamOn?

I believe between two consecutive runs.

This is the example I was thinking of

Ah, that’s much easier! Yes, you can definitely change the material properties table (or just its content) between runs. If you want to be able to control it with macro commands, you could do it with just a Messenger class (which you’d instantiate maybe as a data member of your RunAction). For full generality, you might have a command like

/mysim/setMaterialProperty <material> <propname> <value> [<units>]

and your code would do G4Material::Get(<material>); then access and update the specified material property. This only works for “ConstProperty” cases; for vector properties, you can work out how to write a more complicated command.

After that setting is done, you need to tell Geant4 that things have changed:

//??? runManager->GeometryHasBeenModified();

I’m not 100% about the first line if you just change material properties. The geometry voxelization certainly doesn’t have to be redone, but it’s not obvious to me which of these two directively trigger the recalculation of cross-section tables, for example.

Sorry, I thought you meant about the macro scripts.

I would like to change during a beamOn run, i.e. neutron is absorbed, and set an absorption length of optical photons based on the depth, then generate optical photons.

However, this is good reference material to come back to if I do need to change between runs in the future

So I’m working with scintillation detectors and have looked at changing the material of the scintillator in different runs. I did this by using the messenger class. I believe there are examples you can look at that do this, but I can’t remember off the top of my head. It’s fairly straight-forward to do. You just need to create your material including their property tables in DetectorConstruction and then use the messenger class to be able to change your material using macros.

Hope this helps,

I’ve just had a look and the OpNovice2 example in the extended → optical examples, shows how to change materials using the Messenger class and then macros. That should help you.