-
Notifications
You must be signed in to change notification settings - Fork 29
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
PET/MR Simulation #1007
base: master
Are you sure you want to change the base?
PET/MR Simulation #1007
Changes from all commits
ffcf18b
90bb89c
2b0101d
197011c
9cbffb3
bb10266
1af93e0
4a345a9
1238724
ce5ae00
0155b97
d5e229d
98603dd
d96337b
6b63f39
ee5f012
8a71919
b68e419
848dfe0
125efaa
571a963
67ebe1f
b6ad633
7839a17
2d29816
9812fb7
ea51059
dd5f296
f46a540
30de60e
ca13617
9616b56
93266b5
886d746
7f03816
06832f9
9fcc88d
c28b51f
5075af0
1ed79c9
a7c65a7
d718b52
747a237
5842aa8
dd6efb5
f2f8a02
75f60f9
28baa57
a21a21a
7f025a8
a7d4f7b
844c415
846f59c
12a35c3
33480e3
4a9f981
3555fbd
9ddfed0
f2daae2
c4cac3c
edae1ea
58eb163
3fd31ce
f9bb51c
1ad948b
7512894
269de69
1a2b2d7
3461547
f01d370
e9a03ab
47c0011
2045673
0456b46
b55e744
e7328a8
f1503b5
f433bf1
1631c48
dfe9d85
2bde574
69b2bd9
3d6e2db
a42edd1
91777a3
8959d38
32977f3
b13f97c
ef605c0
2d7aaee
82e34e7
73cfd16
e41c334
332a7fd
2fc8831
8d65e14
6893b1e
6d201e6
2bf7a92
551e5cb
91b157b
4595857
0a6bcdf
ec149e3
dee2cef
f43716b
9fb5267
7719651
64ba984
35cd062
7df20a3
f389a9f
2c49585
aa77667
6cd8ca0
83d6011
b903c7a
1c46c84
b83376c
2511979
6dc7443
7f90d31
34fbe0e
ad4e4e0
e282b0d
9133b0b
7eba8b3
c1d3593
9922df9
819284f
984be53
6d17c46
ce553ea
18e1d0f
889b587
008c93b
fd43556
5991c54
9d331e0
04d5772
e38de5d
db59edc
5734cbb
39d841f
5fae741
eb38f34
9f377ae
69708ce
b3304b8
bebd168
bb83a74
0f1ddc4
bf15e50
0a9e952
ecb1311
cc1a7d6
783625c
e4f1931
884bf7c
3fca946
d369b73
e05a680
5a26ea8
52712a6
39318ee
410ab00
af4ca23
650134c
4b993c7
2006c00
d01aa25
310689a
1a961ce
8a47c38
3d5ca1c
acc459e
4ae5d67
43b903b
c9ae9e5
c9e2a8d
19f224b
855024a
a514c68
70d7621
8c3bf96
d669d60
4884ee3
1b5a312
ef31af4
9756ff7
469d383
5f7e661
d032157
c4a4fcf
bffc423
cbb9700
55cb126
f043013
0bcea11
8c21a7a
c95ba42
d07ee4b
8ee8554
d433293
bf0088d
d016a77
ff8ace0
1519b2f
c2e8e53
0bd675b
4b8112d
f3adc77
5c50b72
8fb6d26
83d25bf
abda270
c7599c0
73d1106
1a4c2f1
a380ed4
e3ac2d4
4848558
122bdc4
b6d7159
786be3a
a235eda
144b4dd
3b9450f
2be642f
4a778d3
d4c49d3
08fad2e
686595f
315c40e
633ba7a
f2ca118
fb599e3
2c207e8
5177e7b
8c0beb8
2b46879
b2df2ce
66ddca5
00aaf3b
c9ed355
8c86d42
3ef5377
e6a876f
ac09847
0745b7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
src/xDynamicSimulation/cDynamicSimulation/Testing/tests_dynamicsimulation.h merge=ours | ||
src/xDynamicSimulation/cDynamicSimulation/Testing/tests_dynamicsimulation.cpp merge=ours | ||
src/xGadgetron/cGadgetron/gadgetron_data_containers.h merge=ours | ||
src/xGadgetron/cGadgetron/gadgetron_data_containers.cpp merge=ours | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,11 @@ | ||
## Ignore Visual Studio temporary files, build results, and | ||
## files generated by popular Visual Studio add-ons. | ||
|
||
# CMake | ||
*.cmake | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. definitely not ignore those! We have them our own |
||
*.make | ||
*.include_cache | ||
*.internal | ||
# User-specific files | ||
*.suo | ||
*.user | ||
|
@@ -20,6 +25,14 @@ bld/ | |
[Bb]in/ | ||
[Oo]bj/ | ||
|
||
# CMake | ||
CMakeCache.txt | ||
CMakeFiles* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. aargh. ignore CMakeFiles.txt ? I think you're trying to ignore files because you did an "in-source" build, which isn't recommended in any case. |
||
|
||
# Makefiles | ||
**/Makefile* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. who knows, maybe we have some valid ones at some point |
||
|
||
|
||
# Roslyn cache directories | ||
*.ide/ | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ if(BUILD_PYTHON) | |
python_pkg_alias(pyiutilities "sirf.pyiutilities") | ||
python_pkg_alias(pReg "sirf.Reg") | ||
python_pkg_alias(pyreg "sirf.pyreg") | ||
python_pkg_alias(pysimulation "sirf.pysimulation") | ||
# convert to python CSV tuple for setup.py configure_file | ||
string(REPLACE ";" "', '" PYTHON_SETUP_PKGS_CSV "${PYTHON_SETUP_PKGS}") | ||
set(PYTHON_SETUP_PKGS_CSV "'${PYTHON_SETUP_PKGS_CSV}'") | ||
|
@@ -42,8 +43,13 @@ if(BUILD_PYTHON) | |
if(PYTHONINTERP_FOUND) | ||
# python setup.py install | ||
if("${PYTHON_STRATEGY}" STREQUAL "SETUP_PY") | ||
message("intalling setup.py") | ||
install(CODE "execute_process(COMMAND\n\ | ||
<<<<<<< HEAD | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. conflict marker |
||
\"${PYTHON_EXECUTABLE}\" setup.py install --prefix ${PYTHON_DEST}\n\ | ||
======= | ||
\"${Python_EXECUTABLE}\" setup.py build install\n\ | ||
>>>>>>> rpe-encoding | ||
WORKING_DIRECTORY \"${PYTHON_DEST}\")") | ||
endif() | ||
endif(PYTHONINTERP_FOUND) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import sys | ||
sys.path.append("/home/sirfuser/devel/buildVM/sources/SIRF/src/xDynamicSimulation/pDynamicSimulation/") | ||
|
||
import numpy as np | ||
|
||
import TissueParameterList as TPL | ||
|
||
root_path = '/media/sf_CCPPETMR/TestData/Input/xDynamicSimulation/pDynamicSimulation/' | ||
xml_path = root_path + 'Cube128/XCAT_TissueParameters_XML.xml' | ||
fpath_output = root_path + 'Fingerprints/XCAT_tissue_parameter_list.npz' | ||
|
||
|
||
# parse file | ||
tpl = TPL.TissueParameterList() | ||
tpl.parse_xml(xml_path) | ||
tpl.print_contents() | ||
|
||
# prepare EPG input array | ||
all_mr_params = tpl.mr_as_array() | ||
mr_params = all_mr_params[:,1:] | ||
mr_params[:,0] /= 100 | ||
mr_params[:,-1] = 0 | ||
|
||
mr_params_unique,idx_inverse = np.unique(mr_params, axis=0, return_inverse=True) | ||
|
||
np.savez(fpath_output, mr_params_full=all_mr_params, mr_parameters=mr_params_unique, unique_idx_inverse=idx_inverse) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
|
||
import numpy as np | ||
from pathlib import Path | ||
import nibabel as nib | ||
|
||
|
||
|
||
num_slices = 10 | ||
Nz = 128 | ||
slab_start = Nz//2 -num_slices//2 | ||
slab_end = Nz//2 + num_slices//2 | ||
|
||
|
||
def preprocess_mvfs(rootpath, folder_pattern, prefix_output): | ||
|
||
fpath_input = Path(rootpath + folder_pattern) | ||
print("looking in {} ".format(fpath_input)) | ||
list_files = sorted(fpath_input.glob('mvf_*')) | ||
|
||
for f in list_files: | ||
print("loading {}".format(f)) | ||
|
||
mvf = nib.load(str(f)) | ||
print("The input motoinfield has size {}".format(mvf.shape)) | ||
|
||
mvf = mvf.slicer[:,:,slab_start:slab_end,:] | ||
print("The output motoinfield has size {}".format(mvf.shape)) | ||
|
||
fname_output = str(prefix_output + folder_pattern + f.name) | ||
print("Storing to {}".format(fname_output)) | ||
nib.save(mvf, fname_output) | ||
|
||
root_path = '/media/sf_CCPPETMR/TestData/Input/xDynamicSimulation/pDynamicSimulation/' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hard-coded |
||
|
||
fpath_input = root_path + 'Cube128/' | ||
fpath_output = root_path + 'Slab128/' | ||
|
||
foldername_resp = 'mvf_resp/' | ||
foldername_card = 'mvf_card/' | ||
|
||
preprocess_mvfs(fpath_input, foldername_resp, fpath_output) | ||
preprocess_mvfs(fpath_input, foldername_card, fpath_output) | ||
|
||
|
||
fname_segmentation = fpath_input + 'label_volume.nii' | ||
seg = nib.load(fname_segmentation) | ||
|
||
print("The input segmentation has size {}".format(seg.shape)) | ||
|
||
seg = seg.slicer[:,:,slab_start:slab_end] | ||
nib.save(seg, fpath_output + 'label_volume.nii') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
''' | ||
bla bla | ||
|
||
Usage: | ||
cartesian_3D_simulation.py [--help | options] | ||
|
||
Options: | ||
--non-interactive do not show plots | ||
''' | ||
|
||
## SyneRBI Synergistic Image Reconstruction Framework (SIRF). | ||
## Copyright 2015 - 2020 Rutherford Appleton Laboratory STFC. | ||
## Copyright 2015 - 2017 University College London. | ||
## Copyright 2015 - 2017 Physikalisch-Technische Bundesanstalt. | ||
## | ||
## This is software developed for the Collaborative Computational | ||
## Project in Synergistic Reconstruction for Biomedical Imaging (formerly CCP PETMR) | ||
## (http://www.ccpsynerbi.ac.uk/). | ||
## | ||
## Licensed under the Apache License, Version 2.0 (the "License"); | ||
## you may not use this file except in compliance with the License. | ||
## You may obtain a copy of the License at | ||
## http://www.apache.org/licenses/LICENSE-2.0 | ||
## Unless required by applicable law or agreed to in writing, software | ||
## distributed under the License is distributed on an "AS IS" BASIS, | ||
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
## See the License for the specific language governing permissions and | ||
## limitations under the License. | ||
|
||
__version__ = '0.1.0' | ||
from docopt import docopt | ||
|
||
args = docopt(__doc__, version=__version__) | ||
|
||
from pUtilities import * | ||
import sirf.Reg as pReg | ||
import sirf.DynamicSimulation as pDS | ||
import sirf.Gadgetron as pMR | ||
|
||
# import engine module | ||
|
||
# process command-line options | ||
show_plot = not args['--non-interactive'] | ||
|
||
from pathlib import Path | ||
import numpy as np | ||
import time | ||
|
||
|
||
def read_motionfields(fpath_prefix): | ||
p = sorted( Path(fpath_prefix).glob('*.nii') ) | ||
files = [x for x in p if x.is_file()] | ||
|
||
temp = [] | ||
for f in files: | ||
print("Reading from {} ... ".format(f)) | ||
img = pReg.NiftiImageData3DDisplacement(str(f)) | ||
temp.append(img) | ||
|
||
data = np.array(temp, dtype=object) | ||
return data | ||
|
||
def set_motionfields_from_path(modyn, fpath_prefix): | ||
|
||
assert_validity(modyn, pDS.MRMotionDynamic) | ||
mvfs = read_motionfields(fpath_prefix) | ||
|
||
for m in mvfs: | ||
modyn.add_displacement_field(m) | ||
|
||
|
||
def get_normed_surrogate_signal(t0_s, tmax_s, Nt, f_Hz): | ||
|
||
t_s = np.linspace(t0_s, tmax_s, Nt) | ||
sig = 0.5 * (1 + np.sin( 2*np.pi*f_Hz*t_s)) | ||
return t_s, sig | ||
|
||
|
||
def main(): | ||
|
||
fpath_testdata_prefix = '/media/sf_CCPPETMR/TestData/' | ||
input_fpath_prefix = fpath_testdata_prefix + 'Input/xDynamicSimulation/pDynamicSimulation/' | ||
output_fpath_prefix = fpath_testdata_prefix + 'Output/xDynamicSimulation/pDynamicSimulation/' | ||
|
||
fpath_xml = input_fpath_prefix + 'Cube128/XCAT_TissueParameters_XML.xml' | ||
|
||
fpath_template_contrast_rawdata = input_fpath_prefix + 'Cube128/CV_nav_cart_128Cube_FLASH_T1_defaultorient.h5' | ||
fpath_template_acquisition_rawdata = input_fpath_prefix + 'General/meas_MID00241_FID69145_Tho_T1_fast_ismrmrd_defaultorient.h5' | ||
|
||
acquisition_ad = pMR.AcquisitionData(fpath_template_acquisition_rawdata) | ||
acquisition_ad = pMR.set_grpe_trajectory(acquisition_ad) | ||
|
||
# configure the simulation | ||
contrast_ad = pMR.AcquisitionData(fpath_template_contrast_rawdata) | ||
contrast_ad = pMR.preprocess_acquisition_data(contrast_ad) | ||
|
||
labels = pReg.NiftiImageData3D( input_fpath_prefix + "Cube128/label_volume_rai.nii" ) | ||
mrsim = pDS.MRDynamicSimulation(labels, fpath_xml) | ||
|
||
mrsim.set_contrast_template_data(contrast_ad) | ||
mrsim.set_acquisition_template_data(acquisition_ad) | ||
|
||
offset_z_mm = 0 | ||
translation = np.array([0, 0, offset_z_mm]) | ||
euler_angles_deg = np.array([0,0,0]) | ||
|
||
offset_trafo = pReg.AffineTransformation(translation, euler_angles_deg) | ||
mrsim.set_offset_trafo(offset_trafo) | ||
|
||
# take CSM from the rawdata itself | ||
# could be replaced if independent way of computing CSM is available | ||
csm = pMR.CoilSensitivityData() | ||
csm.calculate(acquisition_ad) | ||
mrsim.set_csm(csm) | ||
|
||
# set which tissue defines SNR | ||
SNR = 10 | ||
SNR_label = 13 | ||
|
||
mrsim.set_snr(SNR) | ||
mrsim.set_snr_label(SNR_label) | ||
|
||
# configure the surrogates | ||
Nt = 10000 | ||
t0_s = 0 | ||
tmax_s = 60* 5 | ||
|
||
|
||
f_Hz_resp = 0.2 | ||
|
||
t_resp, sig_resp = get_normed_surrogate_signal(t0_s, tmax_s, Nt, f_Hz_resp) | ||
|
||
|
||
# configure the motion | ||
num_motion_states = 4 | ||
# RESP | ||
num_sim_resp_states = num_motion_states | ||
# resp_motion = pDS.MRMotionDynamic( num_sim_resp_states ) | ||
# resp_motion.set_dynamic_signal(t_resp, sig_resp) | ||
# resp_motion.set_cyclicality(False) | ||
# resp_motion.set_groundtruth_folder_prefix(output_fpath_prefix + "output_simulation_3D_motiondata_r_{}_gt_resp".format(num_sim_resp_states)) | ||
# set_motionfields_from_path(resp_motion, input_fpath_prefix + 'Cube128/mvf_resp/') | ||
# mrsim.add_motion_dynamic(resp_motion) | ||
|
||
# | ||
fname_simulation_output = "output_simulation_3DRPE_motiondata_traj_r{}".format(num_sim_resp_states) | ||
|
||
fname_output = output_fpath_prefix + fname_simulation_output + ".h5" | ||
simulated_file = Path(fname_output) | ||
if not simulated_file.is_file(): | ||
|
||
tstart = time.time() | ||
mrsim.simulate_data() | ||
print("--- Required {} minutes for the simulation.".format( (time.time()-tstart)/60)) | ||
mrsim.write_simulation_results(str(simulated_file)) | ||
else: | ||
print("Skipping simulation since output file already exists.") | ||
|
||
# mrsim.save_motion_ground_truth() | ||
|
||
simulated_data = pMR.AcquisitionData(str(simulated_file)) | ||
|
||
csm.calculate(simulated_data) | ||
|
||
AM = pMR.AcquisitionModel() | ||
AM.set_coil_sensitivity_maps(csm) | ||
AM.set_up(simulated_data, csm) | ||
|
||
recon_img = AM.inverse(simulated_data) | ||
recon_nii = pReg.NiftiImageData3D(recon_img) | ||
recon_nii = recon_nii.abs() | ||
|
||
fname_output = output_fpath_prefix + "recon_" + fname_simulation_output + ".nii" | ||
recon_nii.write(fname_output) | ||
|
||
return 1 | ||
|
||
try: | ||
main() | ||
print('\n=== done with %s' % __file__) | ||
|
||
except error as err: | ||
# display error information | ||
print('??? %s' % err.value) | ||
exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we really need this? seems weird to keep it on master.