# Problem with layers\_step\_axl not being set in castor-GATEMacToGeom v3.2.1

**URL:** <https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069>\
**Category:** General Discussions\
**Tags:** pet, bug\_report\
**Created:** [May 28, 2025, 12:19pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069 "2025-05-28T12:19:35Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![mastergari](https://avatars.discourse-cdn.com/v4/letter/m/ccd318/32.png) [@mastergari](https://castor-project.discourse.group/u/mastergari)\
**Post date:** [May 28, 2025, 12:19pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/1 "2025-05-28T12:19:35Z")

</div>

Hi all,

I’ve just started using CASToR and encountered an issue when converting a GATE PET macro to a castor geometry file. The conversion is successful with v3.1.1 but fails with v3.2.1, so the issue appears to be related to the changes to improve multi-layer geometry management.

Here’s what I’ve found from debugging `src/management/gDataConversionUtilities.cc`, and I’d appreciate your input on whether my interpretation and solution are reasonable.

From the GDB debugger:

```auto
Program received signal SIGSEGV, Segmentation fault.
CreateGeomWithCylindrical (a_pathMac="../mac/geometry_layer.mac", a_pathGeom="/opt/castor/castor_v3.2.1/castor_v3.2/config/scanner/geometry_layer.geom") at /opt/castor/castor_v3.2.1/castor_v3.2/src/management/gDataConversionUtilities.cc:4394
4394 if (layers_step_axl[l] - layers_size_axl[l] >= 0)
(gdb) print layers_step_axl[l]
Cannot access memory at address 0x0
(gdb) print layers_size_axl[l]
$1 = 5.2999999999999998

```

Just before this crash, CASToR checks `if(layers_step_trs.size()>0 || layers_step_axl.size()>0)`, and since the former is \> 0, the code continues. In v3.1.1, `layers_step_axl.size()` is 1 and the conversion succeeds, but in v3.2.1, the size is 0 but the vectory is actually empty, so `layers_step_axl[l]` results in a segfault.

Looking further back at the calls to `layers_step_axl.push_back(step_axl)`, one of the key differencs lies within the if/else statements in the blocks of code below. In v3.2.1, the push back lies within an else statement that isn’t executed, and in v3.1.1 there are no if/else statements to prevent the push back.  
**For v3.2.1, lines 4041-4055 are:**

```auto
          if(step_trs > 0) // linear repeater for trs
          {
            layers_step_trs.push_back(step_trs);
          }
          else if (step_axl > 0) // linear repeater for axl
          {
            layers_step_axl.push_back(step_axl);
          }
          else if (step_dph > 0)
            layers_step_dph.push_back(step_dph);
          else // something wrong
          {
            Cerr(" ***** dataConversionUtilities::CreateGeomWithCylindrical()-> There seems to be a problem with layer linear repeater. Please report the error to the castor mailing-list! At line " << line<< endl);
            return 1;
          }

```

Note that when this if/else block is executed, the values of `step_trs`, `step_axl`, and `step_dph` are 3.983300e+00, 5.300000e+00, and 0.000000e+00, respectively.

**For v3.1.1, the corresponding lines (3947-3948) are:**

```auto
          layers_step_trs.push_back(step_trs);
          layers_step_axl.push_back(step_axl);

```

I don’t fully understand the changes that were made and why, or all of the possible use cases. However, if I replace the if/else statements in v3.2.1 with the `push_back` lines immediately below, then conversion completes successfully with the same result as v3.1.1 (apart from the “rsector gap transaxial” which is no longer included in the .geom file).

```auto
          layers_step_trs.push_back(step_trs);
          layers_step_axl.push_back(step_axl);
          layers_step_dph.push_back(step_dph);

```

Are these if/else statements in v3.2.1 necessary or intentional? If so, is there an alternate approach to convert single-layer scanners to ensure all relevant vectors are filled?

Best,  
Matthew

---

<div class="post-metadata">

**Author:** ![mastergari](https://avatars.discourse-cdn.com/v4/letter/m/ccd318/32.png) [@mastergari](https://castor-project.discourse.group/u/mastergari)\
**Post date:** [May 28, 2025, 1:47pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/2 "2025-05-28T13:47:52Z")

</div>

I’m also encountering a similar issue with `castor-GATERootToCastor` where the function `ReadMacCylindrical` tries to access `nLayersRptAxial[l]` when the vector is empty.

After more testing of the RootToCastor conversion, I found CASToR has a slight dependence on the order of commands in the GATE macro which might be causing lines 1906-1907 to be executed too early:

```auto
      if(nLayersRptTransaxial.size()>0 || nLayersRptAxial.size()>0 )
         nb_crystals_layer *= nLayersRptTransaxial[l] * nLayersRptAxial[l];

```

For example, I receive a segfault when configuring my macro as

```auto
/gate/crystal/cubicArray/setRepeatNumberX 4
/gate/crystal/cubicArray/setRepeatNumberY 1
/gate/crystal/cubicArray/setRepeatNumberZ 3

```

However, the conversion is successful when my macro is configured with setRepeatNumberZ appearing before Y:

```auto
/gate/crystal/cubicArray/setRepeatNumberZ 3
/gate/crystal/cubicArray/setRepeatNumberX 4
/gate/crystal/cubicArray/setRepeatNumberY 1

```

I don’t fully understand what’s going wrong with the parsing, but it appears that something is being executed as soon as setRepeatNumberY is pushed back to `nLayersRptTransaxial`. This is problematic if Z hasn’t been parsed first.

I’m not sure if this is directly related to the above problem.

Best,  
Matthew

---

<div class="post-metadata">

**Author:** ![Maxime\_Toussaint](https://avatars.discourse-cdn.com/v4/letter/m/34f0e0/32.png) [@Maxime\_Toussaint](https://castor-project.discourse.group/u/Maxime_Toussaint)\
**Post date:** [May 28, 2025, 8:10pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/4 "2025-05-28T20:10:54Z")

</div>

Greetings,

Would you mind sharing your mac file or a MWE? Those I have do not seem to generate an error with CASToR v3.2.1 and I have a hypothesis I would like to test.

Bests,  
Maxime Toussaint

---

<div class="post-metadata">

**Author:** ![mastergari](https://avatars.discourse-cdn.com/v4/letter/m/ccd318/32.png) [@mastergari](https://castor-project.discourse.group/u/mastergari)\
**Post date:** [May 29, 2025, 9:32am UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/5 "2025-05-29T09:32:43Z")

</div>

Hi Maxime,

Thank you for your reply! The discourse says new users cannot upload attachments, so I’ll try sending the macro and root files in this email.

The commands I’m using are:

1. `castor-GATEMacToGeom -m geometry_layer.mac -o geometry_layer`
2. `castor-GATERootToCastor -i output.root -s geometry_layer -m geometry_layer.mac -o test`
3. `castor-recon -df test_df.Cdh -fout test_recon -it 4:28 -dim 256,256,89 -fov 300,300,247.42 -opti MLEM`

The recon runs to completion, so there are no apparent issues there thankfully.

Best,  
Matthew

(Attachment output.root is missing)

> **(attachments)**
>
> [geometry\_layer.mac](https://castor-project.discourse.group/uploads/short-url/4j4oFCwbvrXWHt1MraLWFFiVRns.mac) (5.01 KB)

---

<div class="post-metadata">

**Author:** ![mastergari](https://avatars.discourse-cdn.com/v4/letter/m/ccd318/32.png) [@mastergari](https://castor-project.discourse.group/u/mastergari)\
**Post date:** [May 29, 2025, 9:38am UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/6 "2025-05-29T09:38:03Z")

</div>

Second attempt, renaming output.root to output.txt to bypass restricted file types.

Cheers,  
Matthew

(Attachment output.txt is missing)

---

<div class="post-metadata">

**Author:** ![mastergari](https://avatars.discourse-cdn.com/v4/letter/m/ccd318/32.png) [@mastergari](https://castor-project.discourse.group/u/mastergari)\
**Post date:** [May 29, 2025, 9:40am UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/7 "2025-05-29T09:40:46Z")

</div>

Final attempt, renaming output.root to output.txt with file size \< 4 MB.

M

> **(attachments)**
>
> [output.txt](https://castor-project.discourse.group/uploads/short-url/igrSOwqvxufZwXhSslS8RDR9pEv.txt) (2.86 MB)

---

<div class="post-metadata">

**Author:** ![Maxime\_Toussaint](https://avatars.discourse-cdn.com/v4/letter/m/34f0e0/32.png) [@Maxime\_Toussaint](https://castor-project.discourse.group/u/Maxime_Toussaint)\
**Post date:** [June 2, 2025, 2:10pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/8 "2025-06-02T14:10:39Z")

</div>

Hi Matthew,

First, sorry for the late reply. I am having a really hard time compiling CASToR with ROOT in my current workstations. I was able to sidestep this for the Mac convertor but I can’t use the ROOT convertor currently…

Nevertheless, I think I understand what is happening. The code seems to assume that layer would be used to describe a change in geometry along the “thickness” of the cylinder, not along its “surface”. In order word, for a scanner with DOI-dependent geometries.

Is there a particular need to use “layer0” over merging block&optical as a “submodule” and promote crystal to “crystal”? Block and optical are repeated in two different axes, so it seems to be mergeable, at first glance.

Note that it is my understanding of the code so it might be wrong. However, it seems that GATE documentation mentions something in that sense for the layer structure:

- “1.4.3.1 (…) **layer** (depth=5) is a (or several, in the case of a phoswich system) radially arranged box(es) inside _crystal_. A repeater should not be used for layers, but the should be build them one by one in the macro”

Thus, I would recommend changing the mac file.

I hope it helps!

---

<div class="post-metadata">

**Author:** ![tmerlin](https://yyz2.discourse-cdn.com/free1/user_avatar/castor-project.discourse.group/tmerlin/32/216_2.png) [@tmerlin](https://castor-project.discourse.group/u/tmerlin)\
**Post date:** [June 4, 2025, 12:16pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/9 "2025-06-04T12:16:09Z")

</div>

Hi Matthew (and Maxime),

Thank you for your very detailed posts.

The changes in v3.2 were due to accommodate different ways to define layers in Gate macros, using repeaters instead of the usual methods as mentioned by Maxime. Unfortunately it brought other issues as you noticed.

There is a _quick_ temporary fix in the Gitlab [(hotfixv.3.2.2)](https://gitlab.com/castor-collaboration/castor/-/tree/hotfix/v3.2.2?ref_type=heads) which separates the processing for each axis and seems to work with your files, at least for the geometry conversion. However it doesn’t address the issue you mentioned regarding the order of the commands in the macro files.

> [@Maxime\_Toussaint](#):
>
> Hi Matthew,
> 
> First, sorry for the late reply. I am having a really hard time compiling CASToR with ROOT in my current workstations. I was able to sidestep this for the Mac convertor but I can’t use the ROOT convertor currently…

If this due to the c++ standard ? The code still assumes c++11 by default, which is not compatible with lastest ROOT versions and must currently be manually changed when compiling with ROOT.

Best,  
Thibaut

---

<div class="post-metadata">

**Author:** ![Maxime\_Toussaint](https://avatars.discourse-cdn.com/v4/letter/m/34f0e0/32.png) [@Maxime\_Toussaint](https://castor-project.discourse.group/u/Maxime_Toussaint)\
**Post date:** [June 4, 2025, 2:02pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/10 "2025-06-04T14:02:15Z")

</div>

About ROOT:

Yes and no… Some versions of ROOT _ **require** _ c++14 or c++17. If you take the latest versions that works on c++11, you can be unlucky and have a ROOT bug that was only repaired in a ROOT that require c++14 [1].

At the end, taking a ROOT v5.x.y worked. Well, it compiled at least!

[1] [Build error from XROOTD - ROOT - ROOT Forum](https://root-forum.cern.ch/t/build-error-from-xrootd/48933)

---

<div class="post-metadata">

**Author:** ![tmerlin](https://yyz2.discourse-cdn.com/free1/user_avatar/castor-project.discourse.group/tmerlin/32/216_2.png) [@tmerlin](https://castor-project.discourse.group/u/tmerlin)\
**Post date:** [June 4, 2025, 6:15pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/11 "2025-06-04T18:15:56Z")

</div>

Just to clarify, old CASToR versions (up to v2.x I think) unnecessarily forced compilation with c++11, but it can also be compiled with c++14/17 if required by ROOT or any other library.

Anyway, you already found a work-around!

---

<div class="post-metadata">

**Author:** ![Maxime\_Toussaint](https://avatars.discourse-cdn.com/v4/letter/m/34f0e0/32.png) [@Maxime\_Toussaint](https://castor-project.discourse.group/u/Maxime_Toussaint)\
**Post date:** [June 5, 2025, 9:07am UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/12 "2025-06-05T09:07:10Z")

</div>

Ohhhhh! Thanks for the clarification, I indeed thought you meant the other way around! Thanks for the tip!

---

<div class="post-metadata">

**Author:** ![mastergari](https://avatars.discourse-cdn.com/v4/letter/m/ccd318/32.png) [@mastergari](https://castor-project.discourse.group/u/mastergari)\
**Post date:** [June 5, 2025, 12:23pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/13 "2025-06-05T12:23:26Z")

</div>

Hi Maxime and Thibaut,

Thanks for sharing the hotfix. I’m not sure if the link is broken or if I don’t have permission to access it, but I’m able to workaround my issue without it. I appreciate the speedy assistance in any case! For clarification, I successfully compiled CASToR v3.2.1 and v3.1.1 on Ubuntu 22.04 with ROOT v6.32.06 (precompiled binary distribution) after changing castor’s CMakeLists.txt to use c++17.

I inherited the macros (and castor commands) as a fully validated system. Thus, I cannot immediately answer why the block & optical geometries were separately implemented instead of a unified submodule. I took your recommendations and successfully merged them into a submodule. I also redefined the system to use Y repetitions instead of X and removed the repeater on layer0. The resulting system appears to produce the same simulation output (aside from submodule, crystal, and layer IDs in the root file), and the macro is castor-compatible without having to reorder any commands, so my hope is that the complete system is still valid.

There are some subtle differences in the .geom files (pasted below) after redefining the macro. In the mandatory fields, the number of crystals and voxels are different (although I specify the voxel info with dim and fov when calling `castor-recon`). I have not reconstructed a distribution of activity yet, but I presume that the number of crystals axial should be consistent with whichever macro was used to generate the data in order to not affect the recon. In the optional fields, the submodule gaps are of slight concern as the axial direction changed from 0 to 0.7, and the transaxial direction changed from 0.3 to 0.3001. Since these are listed as optional, I’m not yet sure if the affect reconstruction.

I admit that I still need to read through the CASToR documentation in detail. In the meantime, could you please let me know if the optional fields as written are used during reconstruction? Also, could you possibly share your insights on the .geom files and whether I should be concerned about the changes in the fields? Again, I hope that the system is still valid if I move forward with these changes.

Thanks in advance!

Positively,  
Matthew

**Original geometry:**

```auto
# MANDATORY FIELDS
modality : PET
scanner name : geometry_layer
number of elements : 20160
number of layers : 1

voxels number transaxial : 37
voxels number axial : 30
field of view transaxial : 432.4
field of view axial : 250.4

description : PET system extracted from GATE macro: ../mac/geometry_layer.mac

scanner radius : 311.8
number of rsectors : 28
number of crystals transaxial : 4
number of crystals axial : 9

crystals size depth : 25
crystals size transaxial : 3.95
crystals size axial : 5.3

# OPTIONAL FIELDS
rsectors first angle : 0
number of rsectors axial : 1
rsector gap axial : 0
number of modules transaxial : 1
number of modules axial : 5
module gap transaxial : 0
module gap axial : 2.8
number of submodules transaxial : 4
number of submodules axial : 1
submodule gap transaxial : 0.3
submodule gap axial : 0
crystal gap transaxial : 0.0333
crystal gap axial : 0
mean depth of interaction : -1
rotation direction : CCW 

```

**Redefined geometry:**

```auto
# MANDATORY FIELDS
modality : PET
scanner name : geometry_layer_redefined
number of elements : 20160
number of layers : 1

voxels number transaxial : 149
voxels number axial : 90
field of view transaxial : 432.4
field of view axial : 250.4

description : PET system extracted from GATE macro: ../mac/geometry_layer_redefined.mac

scanner radius : 311.8
number of rsectors : 28
number of crystals transaxial : 4
number of crystals axial : 3

crystals size depth : 25
crystals size transaxial : 3.95
crystals size axial : 5.3

# OPTIONAL FIELDS
rsectors first angle : -90
number of rsectors axial : 1
rsector gap axial : 0
number of modules transaxial : 1
number of modules axial : 5
module gap transaxial : 0
module gap axial : 2.8
number of submodules transaxial : 4
number of submodules axial : 3
submodule gap transaxial : 0.3001
submodule gap axial : 0.07
crystal gap transaxial : 0.0333
crystal gap axial : 0
mean depth of interaction : -1
rotation direction : CCW

```

---

<div class="post-metadata">

**Author:** ![Maxime\_Toussaint](https://avatars.discourse-cdn.com/v4/letter/m/34f0e0/32.png) [@Maxime\_Toussaint](https://castor-project.discourse.group/u/Maxime_Toussaint)\
**Post date:** [June 5, 2025, 2:52pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/14 "2025-06-05T14:52:38Z")

</div>

In the documentation, there is the following information:

> - number of crystals transaxial: for each layer, number of transverse crystals within a  
> submodule.
> - number of crystals axial: for each layer, number of axial crystals within a submodule.

Thus, I think that “3” corresponds to the expected value following your changes.

Also, since you merged block and optical as a submodule, it can make sense that the gap between the submodules is non-zero in both directions. As for the values, you can try to validate it by hand from your mac file.

As for the difference between the two geom, if the former was produced from the code you modified so that CASToR would not crash, it is possible that the output is slightly wrong.

Finally, I think that `OPTIONAL FIELDS` here means that it is not required to provide them IF their default values correspond to your geometry. So they affect the reconstruction.

Positively is a nice closing word. I think I shall add it to my list XD

---

<div class="post-metadata">

**Author:** ![tmerlin](https://yyz2.discourse-cdn.com/free1/user_avatar/castor-project.discourse.group/tmerlin/32/216_2.png) [@tmerlin](https://castor-project.discourse.group/u/tmerlin)\
**Post date:** [June 6, 2025, 9:12pm UTC](https://castor-project.discourse.group/t/problem-with-layers-step-axl-not-being-set-in-castor-gatemactogeom-v3-2-1/1069/15 "2025-06-06T21:12:48Z")

</div>

Hi Matthew

> [@mastergari](#):
>
> Hi Maxime and Thibaut,
> 
> Thanks for sharing the hotfix. I’m not sure if the link is broken or if I don’t have permission to access it, but I’m able to workaround my issue without it.

Yes a registration to the gitlab is required. I just sent you an invitation link, if you still want to have a look.

> [@mastergari](#):
>
> There are some subtle differences in the .geom files (pasted below) after redefining the macro. In the mandatory fields, the number of crystals and voxels are different (although I specify the voxel info with dim and fov when calling `castor-recon`). I have not reconstructed a distribution of activity yet, but I presume that the number of crystals axial should be consistent with whichever macro was used to generate the data in order to not affect the recon. In the optional fields, the submodule gaps are of slight concern as the axial direction changed from 0 to 0.7, and the transaxial direction changed from 0.3 to 0.3001. Since these are listed as optional, I’m not yet sure if the affect reconstruction.

- The new numbers of axial crystal/submodules reflect your changes as Maxime stated.
- I believe the submodule gap comes from a difference between a setRepeatVector of a volume and its size.
- The `voxels number xxx` variables are indeed default value used for castor-recon image matrix in case none is provided by the user, so they don’t really matter as long as you set them when launching a reconstruction.
- Some fields are marked _optional_ simply as the program will not send an error if they are not provided in the geom file, contrary to the _mandatory_ fields. But they will affect the geometry.

Just for information one can display/print the location of each elements as computed by CASToR using the `castor-scannerLUTExplorer` tool with the path of the created geom file. This could help to check everything is correctly located.

Cheers,  
Thibaut
