-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(potential) axial shift in scatter simulations #495
Comments
@NikEfth possibly you saw something on this when you said that down-sampled images had to use the same downsampling. After writing this up, I think however that the problem is worse than that. |
See some background reading at http://stir.sourceforge.net/wiki/index.php/STIR_FAQ#How_does_the_STIR_coordinate_system_work_.28e.g._for_generate_image.29 |
@KrisThielemans |
Requiring the shift to be zero leads to
This works ok in the "symmetric" test. I've tried the following shared_ptr<VoxelsOnCartesianGrid<float> > tmpl_density( new VoxelsOnCartesianGrid<float>(*original_projdata_info));
...
{
const int new_size_z = 14;
const float zoom_z = static_cast<float>(new_size_z-1)/(water_density->size()-1);
sss->downsample_density_image_for_scatter_points(.2,zoom_z,-1, new_size_z);
} with a few different values of It's now a question on how to handle this. Seems we can throw some errors if this condition isn't satisfied. However, we need to check on all 3 images. Needs a bit of thought. |
I think we need to do the following check for each image const float z_to_middle =
(image.get_max_index() + image.get_min_index())*voxel_size.z()/2.F;
const float z_to_middle_standard =
(scanner.get_num_rings()-1) * scanner.get_ring_distance()/2;
if (abs(z_to_middle - z_to_middle_standard)>.1)
error("..."); i.e. check that it is zoomed consistently with the scanner (see formula above for the "standard" image for a scanner |
These are tests for a symmetric object, checking if the result is symmetric. Also enabled the consistency check mentioned in UCL#495. This means that run_scatter_tests/sh will now fail.
The above suggested test was too strict. Due to the "shift to the middle" strategy, the current code gives the same result with a global shift of all 3 images (which is admittedly weird). So, instead I've introduced a check in 06e2604 that sees if all 3 images are consistent. See here This test seems to catch anomalous cases while letting ones through that do satisfy symmetry tests. Checks add in this commit |
This is now done by default in ScatterSimulation. Removing this avoids problems with UCL#495. - changed recon_test_pack and PET_simulation script/par-file - changed scatter-output file in recon_test_pack to take the new zooming into account. Difference with respect to the previous version is about 4%. (Note that the previous version was incorrect due to UCL#495)
This commit finally closes UCL#495
This has been resolved in the above commits. |
Can this function go?
after #618 |
Is this still an issue? |
actually not sure but it works for blocks on cylindrical |
When the code was written originally, the shift could occur. As I wrote above, I added in checks such that if the user would give images with dimensions such that the result would be wrong, it would throw an error, see here. The issue remains open as #618 should remove this restriction on image dimensions, and then we can add some tests and remove these checks. So, in the current code, as long as the scatter simulation doesn't throw, it will be fine. |
While reviewing #44, I discovered a problem in the original scatter code, existing probably since 2005.
There are 3 images passed to the scatter simulation code: the activity image, the attenuation image and the "zoomed" attenuation image used for finding the scatter points. The issue occurs when any of these images do not have the same "size" in z-direction as the original data (see below). However, this is in practice always the case, especially for the "scatter-point" image.
Coordinate systems
Projectors
For historical reasons, STIR projectors currently "centre" the image with respect to the scanner, i.e. it puts
0+(max_index.z()+min_index.z())/2.F * voxel_size.z()
as the centre (i.e. the image is centred iforigin.z()==0
), see e.g.STIR/src/recon_buildblock/ProjMatrixByBinUsingRayTracing.cxx
Line 655 in 29133a3
This convention causes/d major headaches to @ashgillman in https://github.com/UCL/STIR/projects/1. It is dangerous, e.g. when using
generate_image
, as the location w.r.t. the scanner will change depending on the number of planes. Hence the recommendation to always use the "standard" number of planes.Scatter
This attempts to follow the same convention. However, the scatter simulation code uses downsampled images...
In the scatter code, relevant lines are
STIR/src/scatter_buildblock/sample_scatter_points.cxx
Lines 65 to 67 in 29133a3
STIR/src/scatter_buildblock/single_scatter_integrals.cxx
Lines 100 to 102 in 29133a3
Side note: the scatter code also uses coordinates for the detectors (stored in
detector_points_vector
) which are in the "scanner-centred" coordinate system (used byProjDataInfo::get_m()
etc). (By the way, it still does this by using the out-datedfind_cartesian_coordinates_of_detection
but shifting to the centre, see here and here for the shift. See #105. This is however not a problem here).The problem
The downsampling is generally computed using
zoom_image
, which makes sure that the "physical" coordinate (origin + index*voxel_size
) is consistent before and after zooming, see here.However, the
z_to_middle
shift depends on the number of planes and voxel-size.These 2 conventions are incompatible.
Example
2N-1
planes of voxel-sizeZ
, 0 offset. This is the usual arrangement for a scanner withN
rings and ring-spacing2Z
(i.e. length2NZ
).2NZ
, so new zoomed voxel-sizeZZ=2NZ/7
(corresponding tozoom_z=7/(2N)
).In the original image the middle plane corresponds to the middle of the scanner, which has the "physical coordinate"
(N-1)Z
(as 0 is in centre of first plane of the original image). Indeed, thez_to_middle=(max_index.z()+min_index.z())/2.F * voxel_size.z()
is in the original image(2N-2)Z/2=(N-1)Z
.However, in the zoomed image6ZZ=6*2NZ/7/2
. Aszoom_image
will have made thephysical_coordinate
consistent between the 2 images, we would get the following calculations for the physical coordinate(N-1)Z
for the centred coordinate system(N-1)Z - z_to_middle = 0
(N-1)Z - 6N/7Z = (N/7-1)Z
Conclusion
The scatter-code effectively shifts each of the 3 images (with potentially different amount). From the above, I believe that the shift is
Note that this conclusion seems independent of whatever offset we ask
zoom_image
to use.Our current zooming strategy assumes a zero new offset
STIR/scripts/zoom_att_image.sh
Line 28 in 29133a3
In #44, I've made a test-case with a centred object, testing if the output is symmetric. I had to work somewhat hard to make the test succeed. The current code tests scatter-point image
zoom_z = 1/2
,new_size_z = N
, which indeed gives a 0 shift according to the formula above.The text was updated successfully, but these errors were encountered: