Skip to content
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

View offset #181

Merged
merged 24 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
03ea634
View Offset Enabled
pw351 May 1, 2018
e2d2a65
View Offset test Data Symmetries OK
pw351 May 1, 2018
d4f19a1
test_proj_data_info
pw351 May 1, 2018
0ae8313
test_proj_data_info author and copyrights
pw351 May 1, 2018
ee9082e
make some LORCoordinates safe for non-standard ranges for phi
KrisThielemans May 5, 2018
5229035
corrected view-offset handling
KrisThielemans May 5, 2018
bf20429
Merge branch 'master' into ViewOffset
KrisThielemans May 5, 2018
78f1e23
make scanner_ptr member of ProjDataInfo private again
KrisThielemans May 5, 2018
698e994
Merge branch 'master' into ViewOffset
KrisThielemans Dec 19, 2020
8ad9379
added another to_0_2pi to be safe in phi/view calculations
KrisThielemans Dec 19, 2020
d4c2d65
let interpolating backprojector abort if view-offset non-zero
KrisThielemans Dec 19, 2020
dea210a
updated test scripts for view-offset
KrisThielemans Dec 19, 2020
ebe4c9e
run test_FBP* with view-offset=0
KrisThielemans Dec 19, 2020
af38f6d
Merge branch 'master' into ViewOffset
KrisThielemans Mar 4, 2021
8b64889
added Scanner::>get_names_of_predefined_scanners
KrisThielemans Mar 4, 2021
726ec75
renamed Scanner::get/set_default_intrinsic_tilt()
KrisThielemans Mar 4, 2021
b9c6e7f
[CMake] added STIR_LEGACY_IGNORE_VIEW_OFFSET option (defaulting to OF…
KrisThielemans Mar 4, 2021
0bbe0cc
clarified release notes on view offset
KrisThielemans Mar 5, 2021
dc696ae
removed some unused variables
KrisThielemans Mar 5, 2021
134d432
Take view-mashing into account in view-offset
KrisThielemans Mar 5, 2021
bd3f8f1
clean-up of copyright and documentation on view offset
KrisThielemans Mar 5, 2021
32c4e6f
Modify recon_test_pack/Utahscat600k_ca_seg4.hs for view-offset
KrisThielemans Mar 5, 2021
f8410c8
ForwardProjectorByBinUsingRayTracing calls error() for non-zero offset
KrisThielemans Mar 5, 2021
ee6e7c6
correct copy-paste mistake
KrisThielemans Mar 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,9 @@ if(NOT DISABLE_NLOHMANN_JSON)
endif()
endif()

# Enable version 3 projectors
# Legacy options
option(STIR_PROJECTORS_AS_V3 "Enable STIR version 3 legacy code" OFF)
option(STIR_LEGACY_IGNORE_VIEW_OFFSET "Ignore using scanner view-offset (or intrinsic azimuthal tilt), as in STIR 4 or earlier" OFF)

# NiftyPET projector
if(NOT DISABLE_NiftyPET_PROJECTOR OR NOT DISABLE_Parallelproj_PROJECTOR)
Expand Down
19 changes: 17 additions & 2 deletions documentation/release_5.0.htm
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,18 @@ <h2> Summary for end users (also to be read by developers)</h2>

<h3>Changes breaking backwards compatibility from a user-perspective</h3>
<ul>
<li> </li>
<ul>
<li>
View Offset Support enabled for the PET scanners.
<ul>
<li>For the scanners that have non-zero intrinsic azimuthal tilt angle, reconstructed images will now get rotated.</li>
<li>If you use view mashing, in previous STIR versions images were rotated according to half the number of mashed views. This is now corrected.</li>
</ul>
<strong>WARNING</strong> This means that reconstructed PET images will <strong>not be identical</strong> when either the scanner has non-zero view-offset, or view-mashing is on.<br />
To reflect this change, <code>Scanner::get_default_intrinsic_tilt()</code> has been renamed to <code>get_intrinsic_azimuthal_tilt()</code>.<br />
Note: start angle was already supported for SPECT<br />
Backward compatibility for reconstructed images can be achieved by setting the <tt>STIR_LEGACY_IGNORE_VIEW_OFFSET</tt> CMake option to <tt>ON</tt>. (However, copied sinogram data will then always have the offset set to 0, in contrast to earlier versions of STIR).
</li>
</ul>


<h3>Bug fixes</h3>
Expand Down Expand Up @@ -115,6 +125,8 @@ <h3>New functionality</h3>
<li>
SAFIR input file format now supports a Gaussian LOR randomization, which is applied on the endpoints of each LOR when sorting the listmode events into virtual scanner projection data.
</li>
<li><code>Scanner</code> has now a new <code>static</code> member <code>get_names_of_predefined_scanners</code> returning a list of names.
</li>
</ul>


Expand Down Expand Up @@ -245,6 +257,9 @@ <h3>Other code changes</h3>
<ul>
<li>store data in <code>ProjDataInMemory</code> in the same order as what is used by <code>copy_to</code> and <code>fill_from</code>. This enabled using straight-forward copy. (This change should not affect anyone, except if you relied on a specific order in the buffer before.)
</li>
<li><code>LOR</code> classes now no longer require phi at input to be between 0 and pi,
nor psi to be between 0 and 2 pi. They will standardise the input automatically.
</li>
</ul>

</body>
Expand Down
32 changes: 32 additions & 0 deletions examples/python/print_scanner_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Demo of how to use STIR from python to list some scanner properties

# Copyright 2021 University College London
# Author Kris Thielemans

# This file is part of STIR.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# See STIR/LICENSE.txt for details

#%% Initial imports
import stir
import math

#%% get the list of all scanners
l=stir.Scanner.get_names_of_predefined_scanners()

#%% go through the list to print some properties
for s in l:
sc=stir.Scanner.get_scanner_from_name(s)
if (sc.get_intrinsic_azimuthal_tilt() != 0):
print("{0:30}: intrinsic tilt (degrees): {1:3.2f}".format(sc.get_name(), sc.get_intrinsic_azimuthal_tilt()*180/math.pi))

2 changes: 1 addition & 1 deletion recon_test_pack/FBP2D_test_sim.par
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FBP2DParameters :=
; test file for FBP2D
input file := my_precorrected_sino.hs
input file := my_precorrected_sino${suffix}.hs
xy output image size (in pixels) := 91
zoom := .5

Expand Down
2 changes: 1 addition & 1 deletion recon_test_pack/FBP3DRP_test_sim.par
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FBP3DRPParameters :=
; test file for FBP2D
input file := my_precorrected_sino.hs
input file := my_precorrected_sino${suffix}.hs
xy output image size (in pixels) := 91
zoom := .5

Expand Down
Binary file removed recon_test_pack/Utahscat600k_ca.scn
Binary file not shown.
4 changes: 4 additions & 0 deletions recon_test_pack/Utahscat600k_ca_seg4.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ maximum ring difference per segment := { -4,-3,-2,-1,0,1,2,3,4}
number of rings := 16
number of detectors per ring := 384
distance between rings (cm) := 0.675
; This offset is constructed such that it compensates for the offset implied
; in the view-mashing. This means that the first view will be "vertical"
; as it was in older versions of STIR
view offset (degrees) := -0.46875
number of time frames := 1
image duration (sec) [1]:= 60
image relative start time (sec)[1] := 100
Expand Down
10 changes: 5 additions & 5 deletions recon_test_pack/correct_projdata_simulation.par
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
correct_projdata Parameters :=

input file := my_prompts.hs
output filename := my_precorrected_sino.hs
input file := my_prompts${suffix}.hs
output filename := my_precorrected_sino${suffix}.hs
; use data (1) or set to one (0) :=
apply (1) or undo (0) correction := 1
randoms projdata filename := my_randoms.hs
randoms projdata filename := my_randoms${suffix}.hs

Bin Normalisation type := from projdata
Bin Normalisation From ProjData :=
; only attenuation here for this simulation
normalisation projdata filename:= my_acfs.hs
normalisation projdata filename:= my_acfs${suffix}.hs
End Bin Normalisation From ProjData:=

; scatter term to be subtracted AFTER norm+atten correction
; defaults to 0
;scatter projdata filename := scatter.hs
;scatter projdata filename := scatter${suffix}.hs

END:=
12 changes: 12 additions & 0 deletions recon_test_pack/run_test_simulate_and_recon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ if [ $? -ne 0 ]; then
echo "Error running simulation"
exit 1
fi
# need to repeat with zero-offset now as FBP doesn't support it
zero_view_suffix=_force_zero_view_offset
./simulate_PET_data_for_tests.sh --force_zero_view_offset --suffix $zero_view_suffix
if [ $? -ne 0 ]; then
echo "Error running simulation with zero view offset"
exit 1
fi

error_log_files=""

Expand All @@ -103,13 +110,18 @@ for recon in FBP2D FBP3DRP OSMAPOSL OSSPS; do
isFBP=0
if expr ${recon} : FBP > /dev/null; then
isFBP=1
suffix=$zero_view_suffix
export suffix
echo "Running precorrection"
correct_projdata correct_projdata_simulation.par > my_correct_projdata_simulation.log 2>&1
if [ $? -ne 0 ]; then
echo "Error running precorrection. CHECK my_correct_projdata_simulation.log"
error_log_files="${error_log_files} my_correct_projdata_simulation.log"
break
fi
else
suffix=""
export suffix
fi

# run actual reconstruction
Expand Down
10 changes: 1 addition & 9 deletions recon_test_pack/run_tests_modelling.sh
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,9 @@ done
# Create the appropriate proj_data files
extract_single_images_from_dynamic_image dyn_from_p0005-p5_img_f%dg1d0b0.hv dyn_from_p0005-p5.hv
# if [ ! -r fwd_dyn_from_p0005-p5.S ]; then
rm -f fwd.par
cat <<EOF > fwd.par
Forward Projector parameters:=
type := ray tracing
forward Projector Using Ray Tracing Parameters :=
End Forward Projector Using Ray Tracing Parameters :=
end :=
EOF

for fr in `count 23 28`; do
forward_project fwd_dyn_from_p0005-p5_f${fr}g1d0b0 dyn_from_p0005-p5_img_f${fr}g1d0b0.hv ${INPUTDIR}ECAT_931_projdata_template.hs fwd.par
forward_project fwd_dyn_from_p0005-p5_f${fr}g1d0b0 dyn_from_p0005-p5_img_f${fr}g1d0b0.hv ${INPUTDIR}ECAT_931_projdata_template.hs
done
#fi

Expand Down
49 changes: 46 additions & 3 deletions recon_test_pack/simulate_PET_data_for_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#
# Copyright (C) 2011 - 2011-01-14, Hammersmith Imanet Ltd
# Copyright (C) 2011-07-01 - 2011, Kris Thielemans
# Copyright (C) 2014, University College London
# Copyright (C) 2014,2020 University College London
# This file is part of STIR.
#
# This file is free software; you can redistribute it and/or modify
Expand All @@ -25,14 +25,51 @@
# Author Kris Thielemans
#

echo This script should work with STIR version 3.x, 4.x. If you have
echo This script should work with STIR version 5.x. If you have
echo a later version, you might have to update your test pack.
echo Please check the web site.
echo

command -v generate_image >/dev/null 2>&1 || { echo "generate_image not found or not executable. Aborting." >&2; exit 1; }
echo "Using `command -v generate_image`"

force_zero_view_offset=0
suffix=""
#
# Parse option arguments (--)
# Note that the -- is required to suppress interpretation of $1 as options
# to expr
#
while test `expr -- "$1" : "--.*"` -gt 0
do

if test "$1" = "--force_zero_view_offset"
then
force_zero_view_offset=1
elif test "$1" = "--suffix"
then
suffix="$2"
shift 1
elif test "$1" = "--help"
then
echo "Usage: `basename $0` [--force_zero_view_offset] [--suffix sometext] [install_dir]"
echo "(where [] means that an argument is optional)"
exit 1
else
echo Warning: Unknown option "$1"
echo rerun with --help for more info.
exit 1
fi

shift 1

done

if [ $# -eq 1 ]; then
echo "Prepending $1 to your PATH for the duration of this script."
PATH=$1:$PATH
fi

# first need to set this to the C locale, as this is what the STIR utilities use
# otherwise, awk might interpret floating point numbers incorrectly
LC_ALL=C
Expand Down Expand Up @@ -64,8 +101,14 @@ awk '/END OF INTERFILE/ { print "number of energy windows := 1\nenergy window lo
${template_sino} > tmp_header.hs
mv tmp_header.hs ${template_sino}

if [ $force_zero_view_offset -eq 1 ]; then
new_template_sino=my_DSTE_3D_rd2_template$suffix.hs
force_view_offset_to_zero.sh ${new_template_sino} ${template_sino}
template_sino=${new_template_sino}
fi

# create sinograms
./simulate_data.sh my_uniform_cylinder.hv my_atten_image.hv ${template_sino}
./simulate_data.sh my_uniform_cylinder.hv my_atten_image.hv ${template_sino} 10 ${suffix}
if [ $? -ne 0 ]; then
echo "Error running simulation"
exit 1
Expand Down
21 changes: 12 additions & 9 deletions recon_test_pack/simulate_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
# Author Kris Thielemans
#

if [ $# -lt 3 -o $# -gt 4 ]; then
echo "Usage: `basename $0` emission_image attenuation_image template_sino [ background_value ]"
echo "Creates my_prompts.hs my_randoms.hs my_acfs.hs my_additive_sinogram.hs"
if [ $# -lt 3 -o $# -gt 5 ]; then
echo "Usage: `basename $0` emission_image attenuation_image template_sino [ background_value [suffix] ]"
echo "Creates my_prompts$suffix.hs my_randoms$suffix.hs my_acfs$suffix.hs my_additive_sinogram$suffix.hs"
exit 1
fi

Expand All @@ -34,15 +34,17 @@ if [ $# -gt 3 ]; then
else
background_value=10
fi

if [ $# -gt 4 ]; then
suffix=$5
fi
echo "=== create ACFs"
calculate_attenuation_coefficients --ACF my_acfs.hs ${atten_image} ${template_sino} > my_create_acfs.log 2>&1
calculate_attenuation_coefficients --ACF my_acfs$suffix.hs ${atten_image} ${template_sino} > my_create_acfs.log 2>&1
if [ $? -ne 0 ]; then
echo "ERROR running calculate_attenuation_coefficients. Check my_create_acfs.log"; exit 1;
fi

echo "=== create line integrals"
forward_project my_line_integrals.hs ${emission_image} ${template_sino} forward_projector_proj_matrix_ray_tracing.par > my_create_line_integrals.log 2>&1
forward_project my_line_integrals$suffix.hs ${emission_image} ${template_sino} forward_projector_proj_matrix_ray_tracing.par > my_create_line_integrals.log 2>&1
if [ $? -ne 0 ]; then
echo "ERROR running forward_project. Check my_create_line_integrals.log"; exit 1;
fi
Expand All @@ -51,17 +53,18 @@ fi
echo "=== create constant randoms background"
${INSTALL_DIR}stir_math -s --including-first \
--times-scalar 0 --add-scalar $background_value \
my_randoms my_line_integrals.hs
my_randoms$suffix my_line_integrals$suffix.hs
if [ $? -ne 0 ]; then
echo "ERROR running stir_math"; exit 1;
fi

echo "=== create norm factors"
# currently just 1 as not used in rest of script yet.
stir_math -s --including-first \
--times-scalar 0 --add-scalar 1 my_norm.hs my_line_integrals.hs
--times-scalar 0 --add-scalar 1 my_norm$suffix.hs my_line_integrals$suffix.hs

echo "=== create prompts"
export suffix # used in the .par file to determine filenames
correct_projdata uncorrect_projdata_simulation.par > my_create_prompts.log 2>&1
if [ $? -ne 0 ]; then
echo "ERROR running correct_projdata. Check my_create_prompts.log"; exit 1;
Expand All @@ -71,7 +74,7 @@ fi

echo "=== create additive sinogram for reconstruction"
# need randoms (and scatter) multiplied by ACF and norm (but we don't have a norm here)
stir_math -s --mult my_additive_sinogram.hs my_randoms.hs my_acfs.hs
stir_math -s --mult my_additive_sinogram$suffix.hs my_randoms$suffix.hs my_acfs$suffix.hs
if [ $? -ne 0 ]; then
echo "ERROR running stir_math"; exit 1;
fi
Expand Down
10 changes: 5 additions & 5 deletions recon_test_pack/uncorrect_projdata_simulation.par
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
correct_projdata Parameters :=

input file := my_line_integrals.hs
output filename := my_prompts.hs
input file := my_line_integrals${suffix}.hs
output filename := my_prompts${suffix}.hs
; use data (1) or set to one (0) :=
apply (1) or undo (0) correction := 0
randoms projdata filename := my_randoms.hs
randoms projdata filename := my_randoms${suffix}.hs

Bin Normalisation type := from projdata
Bin Normalisation From ProjData :=
; only attenuation here for this simulation
normalisation projdata filename:= my_acfs.hs
normalisation projdata filename:= my_acfs${suffix}.hs
End Bin Normalisation From ProjData:=

; scatter term to be subtracted AFTER norm+atten correction
; defaults to 0
;scatter projdata filename := scatter.hs
;scatter projdata filename := scatter${suffix}.hs

END:=
3 changes: 2 additions & 1 deletion scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ set(${dir_scripts}
zoom_att_image.sh
get_num_voxels.sh
create_fdef_from_listmode.sh
)
force_view_offset_to_zero.sh
)



Expand Down
33 changes: 33 additions & 0 deletions scripts/force_view_offset_to_zero.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh
# Takes an interfile projdata header, and creates a new one with view-offset set to 0.
#
#
# Copyright (C) 2020, University College London
# This file is part of STIR.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.

# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# See STIR/LICENSE.txt for details
#
# Author: Kris Thielemans

if [ $# -ne 2 ]; then
echo "Usage: `basename $0` output_filename projdata_interfile_header_filename"
echo "sets view-offset to zero"
echo "Warning: this script is unsafe. It doesn't do any checks at all."
exit 1
fi

out_filename=$1
in_filename=$2

set -e
sed -e "s/View offset (degrees).*/View offset (degrees) := 0/" $in_filename > $out_filename
Loading