Coder Social home page Coder Social logo

opengate / opengate Goto Github PK

View Code? Open in Web Editor NEW
37.0 8.0 36.0 8.61 MB

Gate 10 (beta)

Home Page: http://www.opengatecollaboration.org

License: GNU Lesser General Public License v3.0

Python 64.64% Shell 0.03% CMake 0.15% C 0.02% C++ 30.62% Bikeshed 4.54%
medical-physics physics-simulation monte-carlo-simulation python

opengate's Introduction

GitHub tag (latest by date) Read the Docs CI cirrus CI pre-commit.ci status

This is GATE10 beta version. The first non-beta release will be officially announced end of May 2024.

See the User Guide. The current version uses Geant4 11.1.1.

How to install (short version)

Compatible with Python 3.8, 3.9, 3.10, 3.11. Not available for Python 3.12 yet. On Windows multithreading, Qt visualization and the "spawn new subprocess" are not (yet) available.

First, create an environment (not mandatory but highly advised)

python -m venv opengate_env
source opengate_env/bin/activate

or you can use the conda environment.

conda create --name opengate_env python=3.9
conda activate opengate_env

Then install the package opengate. The package opengate_core is automatically downloaded. opengate_core installs Geant4 librairies.

pip install --upgrade pip
pip install --pre opengate

If you already installed the packages and want to upgrade to the latest version:

pip install --upgrade --pre opengate

Once installed, you can run all tests:

opengate_tests

WARNING The first time you run this command, the test data will be downloaded. If the download fails (on some systems), try to add the following command before running opengate_tests:

export GIT_SSL_NO_VERIFY=1

All tests are in the folder here. The test data (binary files) are stored, for technical reasons, in this git: https://gitlab.in2p3.fr/opengamgate/gam_tests_data (which is stored as a git submodule).

WARNING Some tests (e.g. test034) needs gaga-phsp which needs pytorch that cannot really be automatically installed by the previous pip install (at least we don't know how to do). So, in order to run those tests, you will have to install both PyTorch and gaga-phsp first with

pip install torch
pip install gaga-phsp

The documentation is here: https://opengate-python.readthedocs.io/en/latest/user_guide.html

How to install (long version, for developers)

See the documentation: https://opengate-python.readthedocs.io/en/latest/developer_guide.html#installation-for-developers

opengate's People

Contributors

acoussat avatar alexis-pereda avatar dsarrut avatar garaymond avatar gitfuchs avatar guneet19 avatar jmletang avatar kochebina avatar majacquet avatar martidvrk avatar maxaehle avatar maxtousss avatar nkrah avatar pre-commit-ci[bot] avatar tbaudier avatar theokaprel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opengate's Issues

opengate_tests error and pycharm error

Dears,

I followed the installation guide, while in the opengate_tests, all downloads are finished, but there is error:

/////
Look for tests in: /home/hyperion/anaconda3/envs/vgate/lib/python3.10/site-packages/opengate/tests/../tests/src
The data are not correct in: /home/hyperion/anaconda3/envs/vgate/lib/python3.10/site-packages/opengate/tests/../tests/src/../data
Activate LFS and download them with:
git submodule update --init --recursive
/////
the actual data path is ......../tests/data

and in pycharm
when i import opengate as gate

opengate_core is not detected. Be sure to execute these lines before to run python:
export LD_LIBRARY_PATH=/home/hyperion/anaconda3/envs/vgate/lib/python3.10/site-packages/opengate_core.libs:${LD_LIBRARY_PATH}
export LD_PRELOAD=/home/hyperion/anaconda3/envs/vgate/lib/python3.10/site-packages/opengate_core.libs/libG4processes-92d9f07e.so:/home/hyperion/anaconda3/envs/vgate/lib/python3.10/site-packages/opengate_core.libs/libG4geometry-0c687114.so:${LD_PRELOAD}

Segmentation faults when setting attributes of DigitizerHitsCollectionActor

Hi!

I noticed a behavior that seems strange: I get a segmentation violation whenever I try to set the attributes on a DigitizerHitsCollectionActor. For instance, when I try to run test 025, the lines

hc.attributes = [
        "TotalEnergyDeposit",
        "KineticEnergy",
        "PostPosition",
        "TrackCreatorProcess",
        "GlobalTime",
        "TrackVolumeName",
        "RunID",
        "ThreadID",
        "TrackID",
    ]

yield a segmentation fault. The problem disappears when commenting out the lines (but of course the test fails later on). Any idea of what is going on and how to overcome the problem?

Create a phase space with boolean substraction

I'm interesting in creating a phase space with a specific geometry which forced me using boolean subtraction. However, when I use the boolean subtraction, it does not work as long as the thickness of the phase space is lower than ~ 0.1 mm.

EM calculator (for use in dose actor)

This issue serves to document and organize actions around EM actor during the 2023-04-24 hackathon in Cracow.

From @andiresch I got the following problem description:

multithreading for LET Actor / Dose 2 Water calculation does not work yet.
Problem with the G4EMcalculator;
I want to make a GateEMcalculator class that gives us also the possibility to load our own stopping power tables
(e.g. Janni tables, …)

Currently the G4EMcalculator is only used in the LET actor, namely here:
https://github.com/OpenGATE/opengate/blob/master/core/opengate_core/opengate_lib/GateLETActor.cpp#L136
and here:
https://github.com/OpenGATE/opengate/blob/master/core/opengate_core/opengate_lib/GateLETActor.cpp#L146

The code shows some attempts to make it thread safe (SetPixelMutex), which are commented out with "TODO" promises, there should be some backstory to that. What went wrong when you tried to uncomment and run this?

There is no EM calculator usage in the regular dose actor yet, it does not seem to offer "dose to water" functionality in any other way either. It does use the G4AutoLock mechanism, so I guess that it can run in MT mode.

Undefined functions in pet_philips_vereos.py

There are undefined functions in opengate/contrib/pet_philips_vereos.py, namely new_material_nb_atoms() and new_material_weights(). I cannot find them defined anywhere within opengate. It seems that no resource within opengate actually uses them so this is going undetected, but it definitely seems a bug to me.

Name space and imports

I open this as issue to keep track of it.

I think, we should really handle the imports and name space better inside opengate.
Specifically: The init.py in opengate/ include tons of wildcard imports, i.e. from XXX import *. That is considered really bad practice in python and should be avoided, as it mangles up the internal namespace. It also slows down the "import gate" statement tremendously when used in a user script. The reason is, that most modules inside opengate also include an "import gate" statement, so each time the init.py in opengate/ is executed.

I propose to do the following:
We should go through all modules of opengate and make explicit imports of the objects we need in that module, following the namespace structure (=folder structure) of the opengate package.

For example:
the class PhysicsManager (which is defined in opengate/physics/) needs the list object available_additional_physics_lists, which is defined in opengate/physics/.
Currently, the list is accessed via the global opengate namespace as gate.available_additional_physics_lists.
It would be much better to do:
from opengate.physics.helpers_physics import available_additional_physics_lists

In the end, the init.py in opengate/ should be empty!

From the users perspective, it is of course nice if it is not necessary to dig in submodules, but the Simulation class anyhow implements many convenience methods which are directly accessed via:
sim = opengate.Simulation()
sim.XXX

Last point:
Is there really a strong argument to create a module (=python file) for each class? For example:
PhysicsManager is defined in PhysicsManager.py. The import following the internal namespace would be:

from opengate.physics.PhysicsManager import PhysicsManager
but in the module PhysicsManager.py contains nothing else one could import, so there is no point it having it as a module. It wold be better to have:
from opengate.physics import PhysicsManager

So far my thoughts. Some are to trigger a discussion. Resolving the issue with the wildcard imports, I think, is actually mandatory to fix.

Valgrind findings

In this issue I'd like to collect findings from applying valgrind to the Python interpreter while it loads and uses the gam-gate and gam-g4 modules.

This continues OpenGATE/Gate#480.

My current procedure (for the record)

Setup singularity container, download and build Geant4 etc.:
First clone gate-singularity and checkout the gam branch (commit eeb1ca2d), build the Singularity image, and inside the Singularity container, download/build GATE and its dependencies. This is described in more detail in the README.md. Exit and restart the container to update the environment.

gam-g4:
As described in the gam-gate readme.md,

cd /software
git clone --recurse-submodules https://github.com/OpenGATE/gam-g4.git 
cd gam-g4
pip3 install -e . # ignore the error
cd build/temp.*
cmake -DGeant4_DIR=/software/geant4/install/ -DPYTHON_EXECUTABLE=`which python3` -DPYTHON_INCLUDE_DIR=/usr/include/python3.6m -DPYTHON_LIBRARY=/usr/lib/libpython3.6m.so -DITK_DIR=/software/ITK/bin -DROOT_DIR=/software/root-cern/install -DCMAKE_CXX_FLAGS="-Wno-pedantic" -DCMAKE_BUILD_TYPE=Debug .
make -j 1

in order to create the Python module /software/gam-g4/gam_g4/gam_g4.cpython-36m-x86_64-linux-gnu.so. Exit and restart the container to update the environment.

gam-gate:
Then build the Python module gam-gate via

cd /software
git clone --recurse-submodules https://github.com/OpenGATE/gam-gate.git # having git-lfs installed
cd gam-gate
pip3 install -e .

gatetools:
In addition to the gam-gate readme.md, we need the latest gatetools package for Python:

cd /software
git clone --recursive https://github.com/OpenGATE/GateTools.git
cd GateTools
pip install -e .

run tests:
Now we can run the individual tests, e.g.

python3 /software/gam-gate/gam_tests/src/test001_G4ThreeVector.py

To run with valgrind, e.g.

cd /software/gam-gate/gam_tests/src/
valgrind --leak-check=full --track-origins=yes --log-file=valg --suppressions=$ROOTSYS/etc/valgrind-root.supp python3 test001_G4ThreeVector.py

Python package awkward

The test019_linac_phsp_source.py did not run locally on my machine because the package awkward was missing. I think it should be included in the dependency list in the pip configuration.

Phase space source not multithreading compatible

At the moment the phase space source does not seem to be multithreading compatible.

The issue seems to be how to ensure that multiple processes extract different particles from the phase space file.

I am happy to fix it, but I have no idea how to solve this issue. My knowledge about Geant4 multithreading and its implementation for Gate10 is basically non-existent.

Simulation of spectrum is almost mono-energetic instead of broadly distributed

Trying to use the representation of a GE Healthcare NM 670 Discovery detector defined in opengate/contrib/spect_ge_nm670.py, I want to simulate a spectrum of a Tc-99m point source. For some reason the peak at 140.5 keV in the simulation seams to be almost mono-energetic (see Figure 1). Instead, I would expect a broader peak as measured with the actual physical system (see Figure 2). Is there a reason for the simulated peak not to be as broadly distributed?
Comparing the simulated version to the actually measured one (see Figure 3) one can see that the peak area of the measurements is of the same magnitude as the simulated peak which gives reason to the assumption that the simulation is correct.

I attatched the code to simulate the spectrum mentioned above (GE_Healthcare_NM_670_Discovery_Simulations.py).

Figure 1: Simulation of a Tc-99m point souce with GE Healthcare NM 670 Discovery system.

test000_NM_670_140 5 keV_370 kBq_60s
Note: 3.7 MBq were reduced by a factor of 10 because of performance reasons in this case.
Values: test000_NM_670_140.5 keV_370 kBq_60s.txt

Figure 2: Measurement of a Tc-99m souce with GE Healthcare NM 670 Discovery system.

measurement_plot
Values: measurement_values.txt

Figure 3: Comparison between measurement and simulation.

Comparison_measurement_with_simulation

Function not found in ITK module

I am getting:
module 'itk' has no attribute 'ChangeInformationImageFilter'
when trying to run test015_iec_phantom_1.py.

I do not seem to be the first one with this issue in ITK:
https://discourse.itk.org/t/changeinformationimagefilter-missing-from-pip-installed-itk-5-3rc4post3/5375

In short:

  1. Uninstall ITK
  2. Manually remove all traces of ITK from your python environment
  3. re-install ITK

For me, this was:

pip uninstall itk
rm -r /Users/nkrah/.virtualenvs/opengate/lib/python3.9/site-packages/itk*
pip install --upgrade --pre itk

Maybe that helps others.
@tbaudier : Is that an issue normal users (i.e., those who install opengate via pip) might encounter? If so, any way to catch that error or make the user aware?

nan in test041_dose_actor

Sometimes, it seems that test041_dose_actor leads to nan in the uncertainty computation.
How to prevent it?

Deprecated pkg_resources with python 3.11

I got this warning with python 3.11 :

opengate_tests:4: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  __import__('pkg_resources').require('opengate==10.0b3')

Segfaults at the end of a simulation

Here my thoughts about segfaults that occasionally occur at the end of a simulation.

Scenario: You set up a simulation, run it, get the results just fine, but you get a segmentation fault when the script terminates.
In my opinion, this is caused by the interplay between the G4RunManager and references in python.

More specifically:
In a Geant4 application, the user creates the run manager instance at the beginning, registers all the construction classes (geometry, physics, etc) and then runs Initialize. This constructs the relevant G4 objects (volumes, processes, particles, regions, etc.). At the end of the Geant4 application, the user should explicitly delete the RunManager, i.e. call its destructor. This in turn iterates recursively over all constructors and calls their destructors, this deleting objects and setting pointer to nullptr.

Now, in opengate, i.e. in python, we do not explicitly call the RunManager's destructor. This happens when python garbage collects it. In fact, the pybind code specifies "nodelete" for the pointers to objects which are deleted by the RunManager to ensure that python does not delete them. On the other hand, many python objects in opengate hold references to G4Objects, such as logical volumes, physics list etc. I think, the segfaults occur when the RunManager happens to be garbage collected while such objects with g4 reference are still alive because these reference point to obsolete addresses after the RunManager's destructor.

While it is difficult to explicitly trigger garbage collection and inspect the problem (NB: del XXX does NOT necessarily causes garbage collection, but only removes a reference), one can do the following to understand the problem:

def simulate():
    sim = gate.Simulation()
    se = gate.SimulationEngine(sim)

    DO STUFF

    provoke_segfault = False

    # if the RunManager is deleted early, it will cause a segfault
    if provoke_segfault is True:
        del se.g4_RunManager
        return None

    # If a reference is kept outside of the scope of this function
    # all other simulation related objects will be garbage collected
    # before the RunManager is destroyed at the very end
    # --> no segfault
    else:
        return se.g4_RunManager

if __name__ == "__main__":
    rm = simulate()

What's going on:
The SimulationEngine class holds references to other engines and thereby G4 objects. When the object 'se' goes out of scope, i.e. at the end of simulate(), all these objects are likely garbage collected.
By returning a reference to the RunManager, this latter will live on beyond the scope of simulate() and the G4 objects are destroyed when no other python reference exist anymore.
On the other hand, by explicitly deleting the only reference to the RunManager, namely se.g4_RunManager, garbage collection is triggered (at least in CPython, to my knowledge). by the 'se' objects lives on and with it the references to the G4 objects which no longer exist.

It's quite tricky problem, but I think one solution would be a context manager. Roughly:
Every opengate opengate object holding references to G4 objects should implement a method to releases these references. The SimulationEngine should be context-aware, i.e. implement en enter and exit method, so it can be used with an 'with' statement, like "with open(filename) as f: ...'. The exit method should make sure that all release methods are called before existing the context. Then, the Simulation class should implement a "run()" method which does something like this:

def run(self): 
    with SimulationEngine() as se: 
        self.output = se.start()

The SimulationEngine objects (and with it all the hierarchical references to other engines) will be garbage collected when the 'with' context exits, but after the release methods are called. The g4 objects are anyhow not needed anymore and neither the simulation engine, because the simulation object now holds the output.

Going further, and assuming that this is a valid approach, I suggest implementing the release mechanism as part of a BaseClass via a metaclass. Specifically, all attributes pointing at G4Object are stored in a dictionary per class and exposed as properties. A method in the based class can then iterate over these attributes and point them to None to release the reference. Additionally, derived classes can implement their own release method and take care of non-trivial structures holding references to G4 objects.

So far my thoughts. In any case, we need some systematic approach to this RunManager / reference problem. Otherwise, we will always be plagued by segfaults (I fear).

Import a solid from an STL file

Hello, I couldn't find an option for loading an STL file and importing a complex shape in the Python package. From my understanding, this feature seems to be available in GEANT4 through the 'tessellated volume' class, but it doesn't appear to be exposed in opengate. I referenced the following resources for information:

GEANT4 Tessellated Solids: https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/Geometry/geomSolids.html#tessellated-solids
OpenGate Documentation: https://opengate.readthedocs.io/en/latest/defining_a_geometry.html#how-to-build-a-tessellated-volume

I'm eager to explore this capability and would appreciate your guidance or confirmation if I missed this option somewhere in the repository. Thank you!

Valgrind findings, 2/?

Setup:
This issue continues #8, but the setup is different. gam-g4 has been merged into gam-gate since then and I updated the gam branch of https://github.com/maxaehle/gate-singularity. In addition I applied the two fixes in #8 as well as Geant4/geant4#43.

(Next) Finding:
There is a Conditional jump or move depends on uninitialised value(s) message in test009_voxels.py:

C++ backtrace Line numbers refer to ITK@aec9e223 and gam-gate@f80f76f2.
#0  0x0000000004c3f7d2 in _vgr20190ZU_libcZdsoZa_bcmp (s1V=0xbd449ad0, s2V=0x1ffeffca88, n=24) at ../shared/vg_replace_strmem.c:1129
#1  0x000000001eae7bc3 in std::__equal<true>::equal<long> (__first1=0xbd449ad0, __last1=0xbd449ae8, __first2=0x1ffeffca88) at /usr/include/c++/8/bits/stl_algobase.h:814
#2  0x000000001eae79ee in std::__equal_aux<long const*, long const*> (__first1=0xbd449ad0, __last1=0xbd449ae8, __first2=0x1ffeffca88)
    at /usr/include/c++/8/bits/stl_algobase.h:831
#3  0x000000001eae7808 in std::equal<long const*, long const*> (__first1=0xbd449ad0, __last1=0xbd449ae8, __first2=0x1ffeffca88) at /usr/include/c++/8/bits/stl_algobase.h:1049
#4  0x000000001eae75e1 in itk::operator==<3u> (one=..., two=...) at /software/ITK/src/Modules/Core/Common/include/itkIndex.h:537
#5  0x000000001eae730b in itk::ImageRegion<3u>::operator== (this=0xbd449ac8, region=warning: RTTI symbol not found for class 'itk::ImageRegion<3u>'
...) at /software/ITK/src/Modules/Core/Common/include/itkImageRegion.h:232
#6  0x000000001eae6d39 in itk::ImageRegion<3u>::operator!= (this=0xbd449ac8, other=warning: RTTI symbol not found for class 'itk::ImageRegion<3u>'
...) at /software/ITK/src/Modules/Core/Common/include/itkImageRegion.h:235
#7  0x000000001eae4c2a in itk::ImageBase<3u>::SetLargestPossibleRegion (this=0xbd4498c0, region=warning: RTTI symbol not found for class 'itk::ImageRegion<3u>'
...) at /software/ITK/src/Modules/Core/Common/include/itkImageBase.hxx:453
#8  0x000000001eae4d46 in itk::ImageBase<3u>::SetRegions (this=0xbd4498c0, region=warning: RTTI symbol not found for class 'itk::ImageRegion<3u>'
...) at /software/ITK/src/Modules/Core/Common/include/itkImageBase.h:317
#9  0x000000001ebc0228 in set_region<itk::SmartPointer<itk::Image<unsigned short, 3u> > > (img=..., index=..., size=...)
    at /software/gam/src/gam_g4/gam_g4/gam_lib/helpers_itk_image_py.h:70
#10 0x000000001ebb96c9 in declare_itk_image_ptr<itk::SmartPointer<itk::Image<unsigned short, 3u> > >(pybind11::module_&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda(itk::SmartPointer<itk::Image<unsigned short, 3u> >&, pybind11::array_t<int, 17>)#5}::operator()(itk::SmartPointer<itk::Image<unsigned short, 3u> >&, pybind11::array_t<int, 17>) const (this=0x1accbcb8, img=..., size=...) at /software/gam/src/gam_g4/gam_g4/gam_lib/helpers_itk_image_py.h:100
#11 0x000000001ebd512b in pybind11::detail::argument_loader<itk::SmartPointer<itk::Image<unsigned short, 3u> >&, pybind11::array_t<int, 17> >::call_impl<void, declare_itk_image_ptr<itk::SmartPointer<itk::Image<unsigned short, 3u> > >(pybind11::module_&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda(itk::SmartPointer<itk::Image<unsigned short, 3u> >&, pybind11::array_t<int, 17>)#5}&, 0ul, 1ul, pybind11::detail::void_type>(declare_itk_image_ptr<itk::SmartPointer<itk::Image<unsigned short, 3u> > >(pybind11::module_&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda(itk::SmartPointer<itk::Image<unsigned short, 3u> >&, pybind11::array_t<int, 17>)#5}&, std::integer_sequence<unsigned long, 0ul, 1ul>, pybind11::detail::void_type&&) && (this=0x1ffeffcc40, f=...)
    at /software/gam/src/gam_g4/external/pybind11/include/pybind11/cast.h:1414
...
Python backtrace
Traceback (most recent call first):
  <built-in method set_size of PyCapsule object at remote 0x2d3dbdb0>
  File "/software/gam/src/gam_gate/helpers_image.py", line 10, in update_image_py_to_cpp
    cpp_img.set_size(py_img.GetLargestPossibleRegion().GetSize())
  File "/software/gam/src/gam_gate/geometry/ImageVolume.py", line 171, in initialize_image_parameterisation
    gam.update_image_py_to_cpp(self.py_image, self.g4_voxel_param.cpp_edep_image, True)
  File "/software/gam/src/gam_gate/geometry/ImageVolume.py", line 72, in construct
    self.initialize_image_parameterisation()
  File "/software/gam/src/gam_gate/geometry/VolumeManager.py", line 175, in Construct
    vol.construct(self)
  <built-in method Initialize of PyCapsule object at remote 0x1a9128d0>
  File "/software/gam/src/gam_gate/Simulation.py", line 200, in initialize
    self.g4_RunManager.Initialize()
  File "test009_voxels.py", line 88, in <module>

The problematic comparison happens in ITK ImageRegion::operator== where all the three entries of region.m_Index are uninitialized. These uninitialized values come into being by a py::array_t declaration in the code for the Python function set_size. See the above C++ backtrace for how the uninitialized py::array_t is propagated to the problematic equality comparison.

We can fix this by initializing the array:

--- a/gam_g4/gam_g4/gam_lib/helpers_itk_image_py.h
+++ b/gam_g4/gam_g4/gam_lib/helpers_itk_image_py.h
@@ -97,6 +97,8 @@ void declare_itk_image_ptr(pybind11::module &m, const std::string &typestr) {
                                 py::array_t<int, py::array::c_style | py::array::forcecast> size) {
                      py::array_t<int,
                              py::array::c_style | py::array::forcecast> zero_index(3);
+                     int* raw = static_cast<int*>(zero_index.request().ptr);
+                     raw[0] = raw[1] = raw[2] = 0;
                      return set_region(img, zero_index, size);
                  }
             )

pin-photodiode

Hello; Is it possible to use the gamma detectors as a pin-photodiode photo multiplier at Gate?

Geant4 seems to be frozen/sleeping - the GIL is to blame - here is why

This issue does not regard users, but developers. And it is rather a documenting an issue which happened to me, and which might occur to other developers at some point. And interesting to understand in any case.

So here is what happened to me: While working on a branch, I implemented an alternative binding of the G4MTRunManager. The binding includes the function G4MTRunManager::Initialize(). The naïve implementation is:

  .def("Initialize", &G4MTRunManager::Initialize)

When I tried to run a test with threads>1, Geant4 simply stopped at some point, namely when geometry and physics list were apparently set up. No error, no segfault, no further output, no CPU load, just frozen. Umpf. After a scattering cout's through the Geant4 source could, I understood the problem, and why others, like David S, had used a smarter, less naïve binding of the Initialize() function.

Here is what went wrong: G4MTRunManager::Initialize() function first calls the single thread G4RunManager::Initialize() and then does a fake run by calling BeamOn(0); The argument n–event=zero is internally interpreted as fake run and not all steps are performed as would be in a real BeamOn(). The purpose of the fake run is to set-up the worker run managers. BeamOn(0) does trigger ​​G4RunManager::DoEventLoop() and this in turn triggers G4MTRunManager::InitializeEventLoop (the overridden version from the inherited G4MTRunManager!). At the very end, after creating and starting workers, there is a WaitForReadyWorkers(); This function contains beginOfEventLoopBarrier.Wait(GetNumberActiveThreads()); which essentially waits until all workers release locks. Specifically, it triggers a call to G4MTBarrier::Wait() which contains a while(true) loop to repeatedly check the number of locks on the shared resource, and breaks the loop when the number of locks equals the number of threads.

Now, admittedly, I do not understand every detail here, but it is clear that Geant4’s implementation relies on locks to establish whether workers are ready. So when my simulation_engine (i.e., Gate internally) called g4_RunManager.Initialize(), it ended up stuck in the while loop waiting for the locks to decrease, which never happened. Why?

This is where the so-called Global Interpreter Lock comes into play. Read this to understand the details: https://realpython.com/python-gil/, or don’t if you are smarter than I am. Essentially, at least in the CPython implementation, there is a lock (mutex) on all resources linked to the python interpreter. Historically, the GIL was a pragmatic choice to easily integrate C-extensions into python even if they were not thread-safe. What does that have to do with Gate? Well, many objects such as physics lists, are created in python, and then communicated to the Geant4 RunManager (e.g. via SetUserInitializaition). There is thus a lock on these resources, namely the GIL. The multithread mechanism in Geant4, on the other hand, does not know about the GIL and thus cannot account for this additional lock, so the lock counter never decreases sufficiently to satisfy Geant4. A way to resolve this dilemma, without hacking around in the Geant4 code, is to instruct pybind to release the Global Interpreter Lock within the scope of the call to a C++ function, such as Initialize(). One way to achieve this is to replace the naïve

.def("Initialize", &G4MTRunManager::Initialize)

by

      .def("Initialize",
           [](G4MTRunManager *mt) {
             py::gil_scoped_release release;
             mt->Initialize();
           })

The key here is the “py::gil_scoped_release release” statement. It instructs pybind to release the GIL before calling the function Initialize(). There is actually a useful passage in pybind’s doc: https://pybind11.readthedocs.io/en/stable/advanced/misc.html

I think, in the case of Gate/Geant4, it is safe to release the GIL because we know that Geant4 handles shared resources in a thread-safe way. Quite the contrary: the GIL actually breaks G4’s mechanism.

So what I learned from this: Any Geant4 function which relies on Geant4’s MT mechanism based on locks needs to be bound to python with a “py::gil_scoped_release release” statement as above. The serial version G4RunManager::Initialize() does not need this statement (and should not have it) because it does not check locks at any point.

Hope this helps other Gate developers. Let me know your thoughts and please correct me if I misunderstood anything.

Physics list Shielding does not seem to work

During my tests of Gate 10 I discovered that the Shielding physics lists seems to have a problem.

  1. The description in the manual is wrong. Setting.
    phys = sim.get_physics_user_info()
    phys.name = "QGSP_BIC_EMZ"
    Does not work, instead the default physics list is used.
    The following command works
    phys.physics_list_name = "QGSP_BIC_EMZ"

  2. For Shielding and Shielding_EMZ (and other variants) no error is given, although the simulation finishes extremely fast (within seconds) and no data is generated. So presumably this physics list does not work. Using capital letters e.g. SHIELDING causes an error about an unknown physics list.

Tested using Geant4 11.1.1 and Gate10 (current dev branch).

merge repositories

It appears that having two repositories (gam-g4 and gam-gate), initially thought to separate cpp from py code is a bad idea.
One single repo will ease github actions and sync between cpp and py parts of the code.

Folder proposal inside gam-gate:

  • contrib
  • docs
  • external : with pybind11, fmt and dependencies
  • gam_gate -> with g4_bindings, gam_cpp (=old gam_lib), gam_py (old gam_gate)
  • gam_tests

To keep the history : https://stackoverflow.com/questions/13040958/merge-two-git-repositories-without-breaking-file-history/

Installation issue

The installation of the gam-gate went correctly but when importing the module in python I am getting an error.

`Python 3.9.7 (default, Sep 10 2021, 14:59:43)
[GCC 11.2.0] on linux

import gam_gate as gam
gam-g4 is not detected. Be sure to execute these lines before to run python:
Traceback (most recent call last):
File "", line 1, in
File "~/.local/lib/python3.9/site-packages/gam_gate/__init__.py", line 8, in
from .geometry.VolumeManager import __world_name__
File "~/.local/lib/python3.9/site-packages/gam_gate/geometry/VolumeManager.py", line 3, in
import gam_g4 as g4
File "~/.local/lib/python3.9/site-packages/gam_g4/__init__.py", line 28, in
print("export LD_LIBRARY_PATH=" + os.path.join(get_site_packages_dir(), "gam_g4.libs") + ":${LD_LIBRARY_PATH}")
File "~/.local/lib/python3.9/site-packages/gam_g4/__init__.py", line 7, in get_site_packages_dir
site_package = [p for p in site.getsitepackages()
IndexError: list index out of range
`

Phase Space Source limited to one particle type

I might be mistaken, but from what I see in the code, the phase space source uses just one particle type for the phase space.
It seems to ignore the initial particle type of the entry and overwrites it with the passed entry.

I propose to change the source to read the particle type or PDG code directly from the phase space.
This way, also multi particle beams can be simulated (e.g. including secondary neutrons, electrons etc.)

Make fatal raise an Exception

the fatal() function should raise an exception rather than calling sys.exit(-1), so exceptions can be properly pass on.
I will take care of that in a PR coming soon.

dose value and edep value

Hello,

since dose = edep/mass
when I ran the test

# import libraries
import opengate as gate
import numpy as np
import opengate_core as g4
from scipy.spatial.transform import Rotation  # used for describe rotation matrix
import pathlib
import os

'''
General
'''
# path
current_path = pathlib.Path(__file__).parent.resolve()
data_path = current_path/ 'data'
output_path = current_path
# Main Simulation object
sim = gate.Simulation()
ui = sim.user_info
ui.g4_verbose = False # set detailed mode
ui.g4_verbose_level = gate.INFO# or gate.DEBUG
ui.running_verbose_level = gate.RUN # or gate.EVENT
ui.visu = True
ui.visu_type = "vrml"
ui.visu_filename = "visual.wrl"
ui.visu_verbose = False
ui.number_of_threads = 1
ui.random_engine = 'MersenneTwister'
ui.random_seed = 123654 # to make sure every run the same
sim.add_material_database(current_path / 'data' / 'GateMaterials.db')
# units
Bq = gate.g4_units('Bq') # Becquerel radioactivity
m = gate.g4_units('m')
cm = gate.g4_units('cm')
mm = gate.g4_units('mm')
um = gate.g4_units("um")
keV = gate.g4_units('keV')
MeV = gate.g4_units('MeV')
sec = gate.g4_units('second')
gcm3 = gate.g4_units("g/cm3")

'''
Geometry
'''
# world
world = sim.world
world.size = [2 * m, 2 * m, 2 * m]
world.material = "G4_AIR"
waterbox = sim.add_volume("Box","waterbox")
waterbox.mother = 'world'
waterbox.size = [40 * cm, 40 * cm, 40 * cm]
waterbox.translation = [0 * cm, 0 * cm, 0 * cm]
waterbox.material = "G4_WATER"
waterbox.color = [0, 0, 1, 1]

'''
Physics
'''
p = sim.get_physics_user_info()
p.physics_list_name = "G4EmStandardPhysics_option3"  
p.enable_decay = True
p.apply_cuts = True  
cuts = p.production_cuts 
cuts.waterbox.gamma = 100 * um
cuts.waterbox.electron = 100 * um
cuts.waterbox.positron = 100 * um
cuts.waterbox.proton = 100 * um

'''
Sources
'''

# spectrum of gamma
source = sim.add_source("Generic", "gamma")
source.mother =  "waterbox"
source.particle = "gamma" 
source.half_life = 574560 * sec
source.position.type = "sphere"
source.position.radius = 1 * mm
source.position.translation = [10 * cm, 10 * cm, 10 * cm]
source.direction.type = "iso"
source.energy.type = "spectrum" 
w, e = gate.get_rad_energy_spectrum("Lu177") # only for gamma
source.energy.spectrum_energy = e
source.energy.spectrum_weight = w
source.activity = 100000 * Bq / ui.number_of_threads 

# spectrum e-
source = sim.add_source("Generic", "e-")
source.mother =  "waterbox"
source.particle = "e-" 
source.half_life = 574560 * sec
source.position.type = "sphere"
source.position.radius = 1 * mm
source.position.translation = [10 * cm, 10 * cm, 10 * cm]
source.direction.type = "iso"
source.energy.type = "Lu177" # see GenericSource.py line 136 
source.activity = 100000 * Bq / ui.number_of_threads 

'''
Actors
'''
# add DoseActor
dose = sim.add_actor('DoseActor', 'dose')
dose.output = output_path / 'test000_waterbox_edep.mhd' 
dose.mother = "waterbox"
dose.size =  [99, 99, 99]
dose.spacing = [2 * mm, 2 * mm, 2 * mm]
dose.img_coord_system = True 
dose.uncertainty = True 
dose.gray = True
# add stat actor
stats = sim.add_actor('SimulationStatisticsActor', 'Stats')
stats.mother = 'world'
stats.track_types_flag = True

'''
Simulation
'''
sim.initialize() # initialize simulation
sim.apply_g4_command("/run/verbose 2") # verbose
sim.apply_g4_command("/tracking/verbose 2")
sim.apply_g4_command("/event/verbose 2")
sim.start() # start simulation
stats = sim.get_actor('Stats')
print(stats)
stats.write(output_path/'test000_waterbox_stats.txt')

The waterbox is like below:
Projections of test000_waterbox_edep
The edep value of one voxel is 0.5645; while the dose value of the same voxel is 1.1305E-8.
I wonder why the difference is so huge between these two numbers.
image
image
Thank you.
Jing

Need test for PR246

With PR #246

With a motion actor, the second run is not correct in the Navigator. You can see the problem in GateUniqueVolumeId, printing the VolumeDepthID parameters

But for the moment, I cannot provide a test:
The problem was found using a proprietary model of spect. I wanted to reproduce with available ge model in contrib folder without success

Missing import and definition in testsDataSetup.py

The script core/opengate_core/testsDataSetup.py misses an import and a definition, namely

import colored
color_error = colored.fg("red") + colored.attr("bold")

Error occurs only when certain if statements apply.
Fixed in PR #130

Opengate_tests error "The data are not correct"

Trying to install opengate on a plain Ubuntu 22.04.3 LTS system I encountered the following error:

(opengate_env) user@ssmptest:~$ opengate_tests
Geant4 data folder does not exist.
I will create it for you here: /home/user/opengate_env/lib/python3.10/site-packages/opengate_core/geant4_data
... and download the G4 data.
This will take a moment.

Downloading 1/12 https://cern.ch/geant4-data/datasets/G4NDL.4.7.tar.gz
100% [....................................................................] 1114928821 / 1114928821Extracting the data archive (tar) ...
done

... (2/12 to 11/12 were downloaded successfully too)...

Downloading 12/12 https://cern.ch/geant4-data/datasets/G4ENSDFSTATE.2.3.tar.gz
100% [............................................................................] 290745 / 290745Extracting the data archive (tar) ...
done

Done
No Opengate test data available in: /home/user/opengate_env/lib/python3.10/site-packages/opengate_core/../opengate/tests/data
I download it for you.

Done
Look for tests in: /home/user/opengate_env/lib/python3.10/site-packages/opengate/tests/../tests/src
The data are not correct in: /home/user/opengate_env/lib/python3.10/site-packages/opengate/tests/../tests/src/../data
Activate LFS and download them with:
git submodule update --init --recursive

I already tried to update the git submodule as suggested by the error message. This leads to the following error message:
fatal: not a git repository (or any of the parent directories): .git
The files in /tests/src/ and in /tests/data/ were successfully downloaded.

Is there anything I can do to fix this issue?

TypeError: 'Box' object is not callable

After the upgrade of opengate package, i have error as below:

Traceback (most recent call last):
File "D:\PycharmProjects\vGate\main.py", line 3, in
cm = gate.g4_units('cm')
TypeError: 'Box' object is not callable

Creating particles via hard-coded function in SourceEngine

Posted here to keep track of it:

In SourceEngine, the method create_master_source_manager() calls the method CreateAllParticles() on a G4ParticleTable object (a singleton instance actually). This method is defined as lambda in the binding code of the class where it explicitly calls the ConstructParticle() methods of a hard-coded set of particles.

I do not think this is a sane implementation, and the FIXME tag in the create_master_source_manager() suggests that the author also has doubts. ;-)

In my understanding, the ConstructParticle() methods should be called when the RunManager initializes the physics list, and more specifically in G4RunManagerKernel::SetupPhysics(). The physics list implements a ConstructParticle() and ConstructProcess() method (it actually must implement them because they are declared purely virtual in the base class). This in turn calls the constructing method for each particle relevant for the specific physics list, e.g. G4Electron::Electron(). Inside theses methods, it is checked whether the ParticleTable already contains an instance of this particle and if not, an instance is created to which the entry in the table then points.

Therefore, in my understanding, it should be left up to this initialization mechanism to populate the ParticleTable. Particle should not be created manually, but according to the physics list. This also implies that no particles can be retrieved from the ParticleTable before the RunManager has initialized the physics lists because the table only contains nullptr before that moment.

I have not had the time to look into the SourceEngine class and what particle information it needs at which stage, but I guess we need to find some better solution here.

Activate DNA physics per region

We need to check if DNA physics can be activate per regions. Starting point is probably the G4EmDNAPhysicsActivator class and line 107:
const std::vector& regnamesDNA = theParameters->RegionsDNA();

Warning during compilation

I got some warning during compilation (nothing urgent)

 Running command python setup.py develop
    Warning: 'classifiers' should be a list, got type 'tuple'
    /Users/dsarrut/src/py/miniconda3/envs/opengate_3_10/lib/python3.10/site-packages/setuptools/dist.py:519: InformationOnly: Normalizing '10.0beta03
    ' to '10.0b3'
      self.metadata.version = self._normalize_version(
    running develop
    /Users/dsarrut/src/py/miniconda3/envs/opengate_3_10/lib/python3.10/site-packages/setuptools/command/develop.py:40: EasyInstallDeprecationWarning: easy_install command is deprecated.
    !!

            ********************************************************************************
            Please avoid running ``setup.py`` and ``easy_install``.
            Instead, use pypa/build, pypa/installer, pypa/build or
            other standards-based tools.

            See https://github.com/pypa/setuptools/issues/917 for details.
            ********************************************************************************

    !!
      easy_install.initialize_options(self)
    /Users/dsarrut/src/py/miniconda3/envs/opengate_3_10/lib/python3.10/site-packages/setuptools/_distutils/cmd.py:66: SetuptoolsDeprecationWarning: setup.py install is deprecated.
    !!

            ********************************************************************************
            Please avoid running ``setup.py`` directly.
            Instead, use pypa/build, pypa/installer, pypa/build or
            other standards-based tools.

            See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for details.
            ********************************************************************************

    !!
      self.initialize_options()

Doc generation error

The PR #71 introduces a bug in the read the doc generation:
https://readthedocs.org/projects/opengate-python/builds/18138932/

<...>
[AutoAPI] Reading files... [ 95%] /home/docs/checkouts/readthedocs.org/user_builds/opengate-python/checkouts/master/opengate/tests/src/a/helpers_source.py

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/sphinx/events.py", line 94, in emit
    results.append(listener.handler(self.app, *args))
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/extension.py", line 164, in run_autoapi
    if sphinx_mapper_obj.load(
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/mapper.py", line 305, in load
    data = self.read_file(path=path, dir_root=dir_root)
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/mapper.py", line 322, in read_file
    parsed_data = Parser().parse_file(path)
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/parser.py", line 41, in parse_file
    return self._parse_file(
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/parser.py", line 38, in _parse_file
    return self.parse(node)
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/parser.py", line 252, in parse
    data = parse_func(node)
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/parser.py", line 238, in parse_module
    child_data = self._parse_local_import_from(child)
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/parser.py", line 199, in _parse_local_import_from
    original_path = astroid_utils.get_full_import_name(node, alias or name)
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/autoapi/mappers/python/astroid_utils.py", line 57, in get_full_import_name
    module_name = module.relative_to_absolute_name(
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 566, in relative_to_absolute_name
    raise TooManyLevelsError(level=level, name=self.name)
astroid.exceptions.TooManyLevelsError: Relative import with too many levels (1) for module 'helpers_source'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/sphinx/cmd/build.py", line 272, in build_main
    app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/sphinx/application.py", line 261, in __init__
    self._init_builder()
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/sphinx/application.py", line 334, in _init_builder
    self.events.emit('builder-inited')
  File "/home/docs/checkouts/readthedocs.org/user_builds/opengate-python/envs/master/lib/python3.9/site-packages/sphinx/events.py", line 105, in emit
    raise ExtensionError(__("Handler %r for event %r threw an exception") %
sphinx.errors.ExtensionError: Handler <function run_autoapi at 0x7f67941af940> for event 'builder-inited' threw an exception (exception: Relative import with too many levels (1) for module 'helpers_source')

Extension error (autoapi.extension):
Handler <function run_autoapi at 0x7f67941af940> for event 'builder-inited' threw an exception (exception: Relative import with too many levels (1) for module 'helpers_source')

testing failed

Hello,
After I installed the opengate, I test the program by running the sentence :
opengate_tests
However, there is a error like below, does someone know how to solve it?

  File "/home/barbara/anaconda3/envs/mc/bin/opengate_tests", line 8, in <module>
    from opengate.helpers import *

  File "/home/barbara/anaconda3/envs/mc/lib/python3.8/site-packages/opengate/__init__.py", line 7, in <module>
    from .geometry.VolumeManager import __world_name__

  File "/home/barbara/anaconda3/envs/mc/lib/python3.8/site-packages/opengate/geometry/VolumeManager.py", line 3, in <module>
    import opengate_core as g4

  File "/home/barbara/anaconda3/envs/mc/lib/python3.8/site-packages/opengate_core/__init__.py", line 68, in <module>
    check_tests_data_folder()

  File "/home/barbara/anaconda3/envs/mc/lib/python3.8/site-packages/opengate_core/testsDataSetup.py", line 21, in check_tests_data_folder
    folderGit = git.Repo(dataLocation)

  File "/home/barbara/anaconda3/envs/mc/lib/python3.8/site-packages/git/repo/base.py", line 266, in __init__
    self.working_dir: Optional[PathLike] = self._working_tree_dir or self.common_dir

  File "/home/barbara/anaconda3/envs/mc/lib/python3.8/site-packages/git/repo/base.py", line 347, in common_dir
    raise InvalidGitRepositoryError()

git.exc.InvalidGitRepositoryError

Valgrind findings, 3/?

The test004_simple_visu.py makes use of an unitialized variable in GamSourceManager::InitializeVisualization():

    char *argv[1]; 
    fUIEx = new G4UIExecutive(1, argv, "qt");

Here, argv is an array of length 1 containing pointers to char. Its element argv[0] is an uninitialized pointer to a char when it is passed to the constructor of G4UIExecutive.

If you want to pass a particular string as an argument, replace this by

char argv0[] = "someargument";
char *argv[1] = {argv0};
fUIEx = new G4UIExecutive(1, argv, "qt");

Which argument should be passed here?

G4_WATER defined in a materials file

In the test data, there are four material database files that contain a line that (re)defines G4_WATER. Fortunately, opengate handles this correctly (ignoring it, but issuing a warning). But I think it would be good to remove those lines. The data files are:

./data/gate/gate_test044_pbs/data/HFMaterials2014.db
./data/gate/gate_test042_gauss_gps/data/HFMaterials2014.db
./data/gate/gate_test044_pbs_rot_transl/data/HFMaterials2014.db
./data/gate/gate_test044_pbs_unFocused/data/HFMaterials2014.db

These files are not here on github (otherwise I could have simply made a PR for this) but on the in2p3 gitlab server, hence this issue.

opengate tests not running in WSL2

In WSL2, opengate installs successfully. However, when attempting to run opengate-tests :

ubuntu@F-P-Phys-02:~$ opengate_tests
Traceback (most recent call last):
  File "/home/ubuntu/.local/bin/opengate_tests", line 7, in <module>
    from opengate.helpers import *
  File "/home/ubuntu/.local/lib/python3.10/site-packages/opengate/__init__.py", line 6, in <module>
    from .geometry.VolumeManager import __world_name__
  File "/home/ubuntu/.local/lib/python3.10/site-packages/opengate/geometry/VolumeManager.py", line 3, in <module>
    import opengate_core as g4
  File "/home/ubuntu/.local/lib/python3.10/site-packages/opengate_core/__init__.py", line 62, in <module>
    from .opengate_core import *
ImportError: libICE.so.6: cannot open shared object file: No such file or directory

Consolidate API of Class Simulation

Keep only

  • add_volume add_source add_actor add_filter add_material_database
  • everything else is in the managers (including all physics)
  • add Documentation (and example to dump volume trees etc)

Optical Data output number is only number of primaries

Hi!
I'm currently working with Gate9.3 and trying out Optical Simulation with Scintillation processes.
It's working fine thus far, except when I try to generate Optical Data with:

/gate/output/root/setRootOpticalFlag 1

the ROOT Branch only contains Data Points to the number of Primaries, in contrast to the number of actual Optical Photons, which I identified are generated in the crystal using actors and the Hits Collection.

Thank you very much for your hard work!
Kind regards

Different behavior for translation and rotation when I create an object and when I repeat it

When I create an object in pythonGate, It seems to a dictionary but i can't access to the translation or rotation parameter directly using the dictionnary. I have to use .translation or . rotation, and it apply a translation/rotation without changing the starting translation or rotation vector.

If I want to repeat this object N times, I will create a list of N dictionnaries, and, this time, I can access to them and I will modify the translation or the rotation vector reference, which means that I apply a translation or rotation, but I don't keep the starting translation or rotation vector.

ITK TypeError - resolved by updating ITK

For info:
test058_calc_uncertainty_MT.py was failing because of a TypeError raised by ITK. Specifically:
TypeError: in method 'itkImageIOFactory_CreateImageIO', argument 1 of type 'char const *'

After updating ITK (via pip) from 5.2.1.post1 to 5.3.0, the error is gone.

If you get a similar error, try updating ITK first, by
pip install itk --upgrade

Downloading / updating G4 data

I just banged my had head for a moment because my simulation would not start because opengate could not find the G4 data files. Sure enough, the files in core/opengate_core/geant4_data were outdated. I think, what had happened is: I pulled a new version of opengate into my local repo with new paths set in the g4DataPath dictionary in g4DataSetup.py. The simulation then looks for data in these paths, but does not find them. The check_G4_data_folder function, which is in init.py in opengate_core and thus called upon "import opengate_core" finds the geant4_data folder, but does not detect that the subfolders are outdated. Therefore, the G4 data is not updated.

I propose to refine the check_G4_data_folder function to actually check the subfolders against the g4DataPath dictionary.

If there are no objections, I will create a PR for this in the next days.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.