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:
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:
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:
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).
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