-
Couldn't load subscription status.
- Fork 99
Description
The rotation for images corresponding to ROOT files is currently confusing and largely undocumented. There are 2 keywords in the .hroot file:
STIR/examples/samples/root_header.hroot
Line 13 in 4221fc3
| View offset (degrees) := 0 |
STIR/examples/samples/root_header.hroot
Line 45 in 4221fc3
| offset (num of detectors) := 0 |
offset (num of detectors)
The offset (num of detectors) is used to change the detector numbering
STIR/src/IO/InputStreamFromROOTFileForCylindricalPET.cxx
Lines 119 to 120 in 4221fc3
| crystal1 += offset_dets; | |
| crystal2 += offset_dets; |
The offset (num detectors) keyword is defined here, but there is no default set for it in InputStreamFromROOTFile::set_defaults which is arguably a bug.
additional rotations in the code
Unfortunately, going through the code, there are additional offsets being applied
STIR/src/IO/InputStreamFromROOTFileForCylindricalPET.cxx
Lines 115 to 116 in 4221fc3
| crystal1 -= half_block; | |
| crystal2 -= half_block; |
where
STIR/src/IO/InputStreamFromROOTFileForCylindricalPET.cxx
Lines 53 to 55 in 4221fc3
| half_block = module_repeater_y * submodule_repeater_y * crystal_repeater_y / 2 - 1; | |
| if (half_block < 0 ) | |
| half_block = 0; |
(note that this uses integer division, which will be surprising) and
STIR/src/listmode_buildblock/CListRecordROOT.cxx
Lines 69 to 70 in 4221fc3
| det1 = crystal1 + quarter_of_detectors; | |
| det2 = crystal2 + quarter_of_detectors; |
where
| quarter_of_detectors = static_cast<int>(scanner_sptr->get_num_detectors_per_ring()/4.f); |
This is a 90 degrees rotation, but it also uses integer division, so this would create some small unexpected rotation if the total number of crystals is not a multiple of 4.
view offset
This is a general STIR functionality (also used in Interfile proj-data etc) that tells the projectors the relation between the image orientation and the projection data (and hence the detectors). If view offset is zero, the first view is assumed to be vertical (and hence first crystal, after the above ROOT-specific detector offsets, assumed to be at the top of the scanner).
GATE macros
GATE allows arbitrary location of detectors (STIR does not yet). STIR does not read the GATE macros. It is therefore your responsibility to make these 2 match up.
The additional rotations above seem to come from the fact that by default, GATE puts the (middle of the) first module on the horizontal GATE axis (can someone confirm this?).
As STIR currently ignores block structure (pending #577), the relevant calculation is an approximation, but I believe that if offset (num of detectors)=0, we should have roughly
view offset (in degrees) = 360 * ( num_blocks_per_bucket*num_crystals_per_block - 1) / 2. / num_crystals_per_ring
However, the half_block calculation interferes with this. I thought we had already removed this, but apparently not. @robbietuk what do you think?
Problems
Aside from the fact that this is all a bit of a mess, changing the crystal numbering with these internal offsets is a bad idea due to potential conflicts with the normalisation code (which will assume that detector 0 starts at a block/bucket to use symmetries).