Skip to content

Commit

Permalink
Merge branch 'master' into OSSPS_gamma
Browse files Browse the repository at this point in the history
  • Loading branch information
evgueni-ovtchinnikov authored Dec 6, 2023
2 parents 8398925 + 031d428 commit 11d5e55
Show file tree
Hide file tree
Showing 47 changed files with 749 additions and 514 deletions.
2 changes: 2 additions & 0 deletions .bandit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
skips:
- "B101" # warning about assert
4 changes: 3 additions & 1 deletion .codacy.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
exclude_paths:
- '**.md'
- '**.md'
assert_used:
- skips: ['*test*.py', 'test*.py']
2 changes: 1 addition & 1 deletion .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ Gemma Fardell <[email protected]> <[email protected]>
Sam D. Porter <[email protected]>
Matthew Strugari <[email protected]>
Matthew Strugari <[email protected]> <[email protected]>

Toni Reeves <[email protected]>

3 changes: 0 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
- Several allocate methods in STIR.py, Gadgetron.py and Reg.py are replaced with just one allocate in DataContainer class that does not copy data between Python and C++.
- `return None` in the method `Datacontainer.shape()` replaced with more Pythonesque `return (0,)`.

* MR
- Handling of "irregular" ISMRMRD acquisitions hit what appears to be a bug in recent Gadgetron (HEAD detached at 0670db84). A quick fix applied, Gadgetron issue to be raised.

## v3.5.0

* GitHub Action: remove temporarily the Ubuntu 20.04 build, #1178
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ else(DISABLE_PYTHON)
endif(DISABLE_PYTHON)


option(DISABLE_Matlab "Disable building SIRF matlab support" OFF)
option(DISABLE_Matlab "Disable building SIRF matlab support" ON)
if (DISABLE_Matlab)
message(STATUS "Matlab support disabled")
else(DISABLE_Matlab)
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ This software is the main output of [SyneRBI](https://www.ccpsynerbi.ac.uk), the
Platform for Synergistic Reconstruction for Biomedical Imaging (formerly CCP PETMR).

Please start with our latest [User's Guide](doc/UserGuide.md).
See [our Wiki page for installation instructions](https://github.com/SyneRBI/SIRF/wiki/Installation-instructions).

You can also [download a VM](https://doi.org/10.5281/zenodo.2707911) with SIRF and related software preinstalled.
## How to obtain SIRF
There are multiple ways to obtain a binary version of SIRF, please check them out in our documentation page [how to obtain SIRF](https://github.com/SyneRBI/SIRF/wiki/How-to-obtain-SIRF)
or [our Wiki page for installation instructions](https://github.com/SyneRBI/SIRF/wiki/Installation-instructions).

# Where is everything installed?
## Where is everything installed?

SIRF largely follows the usual directory structure with some minor tweaks. When using
the default options when building SIRF, you will get (most of the) following, depending
Expand All @@ -40,7 +41,7 @@ what was found/built:
[gh-action-link]: https://github.com/SyneRBI/SIRF/actions/workflows/build-test.yml
[travis-badge]: https://travis-ci.org/SyneRBI/SIRF.svg?branch=master
[travis]: https://travis-ci.org/SyneRBI/SIRF
[style-badge]: https://api.codacy.com/project/badge/Grade/392861b4085f4f438d12c41029f86b47
[style-link]: https://www.codacy.com/gh/SyneRBI/SIRF?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=SyneRBI/SIRF&amp;utm_campaign=Badge_Grade
[style-badge]: https://app.codacy.com/project/badge/Grade/392861b4085f4f438d12c41029f86b47
[style-link]: https://app.codacy.com/gh/SyneRBI/SIRF/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade
[zenodo-badge]: https://zenodo.org/badge/DOI/10.5281/zenodo.2707911.svg
[zenodo-link]: https://doi.org/10.5281/zenodo.2707911
13 changes: 7 additions & 6 deletions examples/Python/MR/acquisition_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@
from docopt import docopt
args = docopt(__doc__, version=__version__)

from ast import literal_eval
from sirf.Utilities import error, examples_data_path, existing_filepath

# import engine module
exec('from sirf.' + args['--engine'] + ' import *')
# import MR engine module
import importlib
mr = importlib.import_module('sirf.' + args['--engine'])

# process command-line options
data_file = args['--file']
Expand All @@ -57,7 +58,7 @@ def main():
input_file = existing_filepath(data_path, data_file)

# acquisition data will be read from an HDF file input_file
acq_data = AcquisitionData(input_file, True)
acq_data = mr.AcquisitionData(input_file, True)

# the raw k-space data is a list of different readouts
# of different data type (e.g. noise correlation data, navigator data,
Expand Down Expand Up @@ -85,7 +86,7 @@ def main():

# inspect the first readout flag
flags0 = acq_data.get_ISMRMRD_info('flags', range(1))
if flags0 & IMAGE_DATA_MASK:
if flags0 & mr.IMAGE_DATA_MASK:
print('first readout is image data')
else:
# should see this if input data file is test_2D_2x.h5
Expand Down Expand Up @@ -143,7 +144,7 @@ def main():
# direction. So far only the removal of readout oversampling and noise and
# asymmetric echo adjusting is implemented
print('pre-processing acquisition data...')
processed_acq_data = preprocess_acquisition_data(acq_data).abs()
processed_acq_data = mr.preprocess_acquisition_data(acq_data).abs()
acq_max = processed_acq_data.maximum(processed_acq_data*10)
acq_min = processed_acq_data.minimum(processed_acq_data*10)
print('norm of acq_data: %f' % processed_acq_data.norm())
Expand Down
34 changes: 16 additions & 18 deletions examples/Python/MR/acquisition_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@
from docopt import docopt
args = docopt(__doc__, version=__version__)

from sirf.Utilities import error, examples_data_path, existing_filepath

# import engine module
exec('from sirf.' + args['--engine'] + ' import *')
import importlib
mr = importlib.import_module('sirf.' + args['--engine'])

# process command-line options
data_file = args['--file']
Expand All @@ -55,23 +58,21 @@ def main():
input_file = existing_filepath(data_path, data_file)

# acquisition data will be read from an HDF file input_file
AcquisitionData.set_storage_scheme('memory')
acq_data = AcquisitionData(input_file)
mr.AcquisitionData.set_storage_scheme('memory')
acq_data = mr.AcquisitionData(input_file)
print('---\n acquisition data norm: %e' % acq_data.norm())

# pre-process acquisition data
print('---\n pre-processing acquisition data...')
processed_data = preprocess_acquisition_data(acq_data)
processed_data = mr.preprocess_acquisition_data(acq_data)
print('---\n processed acquisition data norm: %e' % processed_data.norm())

# perform reconstruction to obtain a meaningful ImageData object
# (cannot be obtained in any other way at present)
# if processed_data.is_undersampled():
if acq_data.is_undersampled():
recon = CartesianGRAPPAReconstructor()
recon = mr.CartesianGRAPPAReconstructor()
recon.compute_gfactors(False)
else:
recon = FullySampledReconstructor()
recon = mr.FullySampledReconstructor()
recon.set_input(processed_data)
print('---\n reconstructing...')
recon.process()
Expand Down Expand Up @@ -104,24 +105,20 @@ def main():
print('patient table positions:')
print(ptp)

# sort processed acquisition data;
# sorting currently performed with respect to (in this order):
# - repetition
# - slice
# - kspace encode step 1
# sort processed acquisition data
print('---\n sorting acquisition data...')
processed_data.sort()

# compute coil sensitivity maps
print('---\n computing coil sensitivity maps...')
csms = CoilSensitivityData()
csms = mr.CoilSensitivityData()
csms.calculate(processed_data)

# create acquisition model based on the acquisition parameters
# stored in processed_data and image parameters stored in reconstructed_images
## acq_model = AcquisitionModel(processed_data, reconstructed_images)
acq_model = AcquisitionModel()
acq_model.set_up(processed_data, reconstructed_images)
acq_model = mr.AcquisitionModel(processed_data, reconstructed_images)
## acq_model = mr.AcquisitionModel()
## acq_model.set_up(processed_data, reconstructed_images)
acq_model.set_coil_sensitivity_maps(csms)

# use the acquisition model (forward projection) to produce simulated
Expand All @@ -134,7 +131,8 @@ def main():
simulated_acq_data.write(output_file)

# display simulated acquisition data
#simulated_acq_data.show(title = 'Simulated acquisition data (magnitude)')
if show_plot:
simulated_acq_data.show(title = 'Simulated acquisition data (magnitude)')

print('\n--- Computing the norm of the acquisition model operator...')
acqm_norm = acq_model.norm()
Expand Down
17 changes: 9 additions & 8 deletions examples/Python/MR/coil_sensitivity_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@
from docopt import docopt
args = docopt(__doc__, version=__version__)

from pUtilities import *
from sirf.Utilities import error, examples_data_path, existing_filepath, show_3D_array

# import engine module
exec('from sirf.' + args['--engine'] + ' import *')
import importlib
mr = importlib.import_module('sirf.' + args['--engine'])

# process command-line options
data_file = args['--file']
Expand All @@ -59,20 +60,20 @@ def main():
input_file = existing_filepath(data_path, data_file)
#
# acquisition data will be read from an HDF file input_file
AcquisitionData.set_storage_scheme('memory')
mr.AcquisitionData.set_storage_scheme('memory')

acq_data = AcquisitionData(input_file)
acq_data = mr.AcquisitionData(input_file)
#
# pre-process acquisition data
processed_data = preprocess_acquisition_data(acq_data)
processed_data = mr.preprocess_acquisition_data(acq_data)
#
# sort k-space data into a 2D Cartesian matrix for each coil
processed_data.sort()

# 2. Calculate coil sensitivity maps directly from the raw k-space data:

# create coil sensitivity object
CSMs = CoilSensitivityData()
CSMs = mr.CoilSensitivityData()
#
# set number of smoothing iterations to suppress noise
CSMs.smoothness = nit
Expand All @@ -98,13 +99,13 @@ def main():
# SSRS and Inati methods:

# create coil images object
CIs = CoilImagesData()
CIs = mr.CoilImagesData()
# calculate coil sensitivity maps by dividing each coil image data by the
# Square-Root-of-the-Sum-of-Squares over all coils (SRSS);
# (niter = nit) sets the number of smoothing iterations applied
# to the image data prior to the calculation of the coil sensitivity maps
CIs.calculate(processed_data)
CSs = CoilSensitivityData()
CSs = mr.CoilSensitivityData()
print('B) calculating from coil images...')
CSs.calculate(CIs, method='SRSS(niter=%d)' % nit)
diff = CSs - CSMs
Expand Down
13 changes: 9 additions & 4 deletions examples/Python/MR/fully_sampled_recon.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@
from docopt import docopt
args = docopt(__doc__, version=__version__)

import numpy

from sirf.Utilities import error, examples_data_path, existing_filepath

# import engine module
exec('from sirf.' + args['--engine'] + ' import *')
import importlib
mr = importlib.import_module('sirf.' + args['--engine'])

# process command-line options
data_file = args['--file']
Expand All @@ -58,7 +63,7 @@ def main():
# bruker_to_ismrmrd on https://github.com/ismrmrd/.
# Acquisition data will be read from an HDF file input_file
print('---\n reading in file %s...' % input_file)
acq_data = AcquisitionData(input_file)
acq_data = mr.AcquisitionData(input_file)

# pre-process acquired k-space data:
# prior to image reconstruction several pre-processing steps such as
Expand All @@ -67,12 +72,12 @@ def main():
# direction. So far only the removal of readout oversampling and noise and
# asymmetric echo adjusting is implemented
print('---\n pre-processing acquisition data...')
processed_data = preprocess_acquisition_data(acq_data)
processed_data = mr.preprocess_acquisition_data(acq_data)

# set up reconstruction:
# create a reconstruction object using 2D inverse Fourier transform and
# provide pre-processed k-space data as input
recon = FullySampledReconstructor()
recon = mr.FullySampledReconstructor()
recon.set_input(processed_data)

# perform reconstruction
Expand Down
21 changes: 13 additions & 8 deletions examples/Python/MR/grappa_and_steepest_descent.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@
from docopt import docopt
args = docopt(__doc__, version=__version__)

import numpy

from sirf.Utilities import error, examples_data_path, existing_filepath

# import engine module
exec('from sirf.' + args['--engine'] + ' import *')
import importlib
mr = importlib.import_module('sirf.' + args['--engine'])

# process command-line options
data_file = args['--file']
Expand All @@ -70,16 +75,16 @@ def main():
input_file = existing_filepath(data_path, data_file)

# acquisition data will be read from an HDF file input_data
AcquisitionData.set_storage_scheme('memory')
acq_data = AcquisitionData(input_file)
mr.AcquisitionData.set_storage_scheme('memory')
acq_data = mr.AcquisitionData(input_file)

# pre-process acquisition data
print('---\n pre-processing acquisition data...')
preprocessed_data = preprocess_acquisition_data(acq_data)
preprocessed_data = mr.preprocess_acquisition_data(acq_data)
preprocessed_data_norm = preprocessed_data.norm()

# perform reconstruction
recon = CartesianGRAPPAReconstructor()
recon = mr.CartesianGRAPPAReconstructor()
recon.set_input(preprocessed_data)
recon.compute_gfactors(False)
print('---\n reconstructing...')
Expand All @@ -95,7 +100,7 @@ def main():
return

# compute coil sensitivity maps
csms = CoilSensitivityData()
csms = mr.CoilSensitivityData()
print('---\n sorting acquisition data...')
preprocessed_data.sort()
print('---\n computing sensitivity maps...')
Expand All @@ -104,7 +109,7 @@ def main():
# create acquisition model based on the acquisition parameters
# stored in preprocessed_data and image parameters stored in
# image_data
acq_model = AcquisitionModel(preprocessed_data, image_data)
acq_model = mr.AcquisitionModel(preprocessed_data, image_data)
acq_model.set_coil_sensitivity_maps(csms)

start_val = 0.001
Expand All @@ -131,7 +136,7 @@ def main():
image_data = image_data - grad * tau
if (i%10 == 0 or i == niter - 1) and show_plot:
it = i + 1
title = 'Steepest-descent-refined image data, iteration %d' % it
title = 'Image data computed by steepest descent at iteration %d' % it
image_data.show(zyx=zyx, slice=slc, title=title, cmap=None, \
postpone=(i < niter - 1))

Expand Down
13 changes: 8 additions & 5 deletions examples/Python/MR/grappa_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@
from docopt import docopt
args = docopt(__doc__, version=__version__)

from sirf.Utilities import error, examples_data_path, existing_filepath

# import engine module
exec('from sirf.' + args['--engine'] + ' import *')
import importlib
mr = importlib.import_module('sirf.' + args['--engine'])

# process command-line options
data_file = args['--file']
Expand All @@ -82,19 +85,19 @@ def main():

# Create an acquisition container of type AcquisitionData
print('---\n reading in file %s...' % input_file)
AcquisitionData.set_storage_scheme('memory')
mr.AcquisitionData.set_storage_scheme('memory')

acq_data = AcquisitionData(input_file)
acq_data = mr.AcquisitionData(input_file)

# Pre-process this input data.
# (Currently this is a Python script that just sets up a 3 chain gadget.
# In the future it will be independent of the MR recon engine.)
print('---\n pre-processing acquisition data...')
preprocessed_data = preprocess_acquisition_data(acq_data)
preprocessed_data = mr.preprocess_acquisition_data(acq_data)

# Perform reconstruction of the preprocessed data.
# 1. set the reconstruction to be for Cartesian GRAPPA data.
recon = CartesianGRAPPAReconstructor();
recon = mr.CartesianGRAPPAReconstructor();

# 2. set the reconstruction input to be the data we just preprocessed.
recon.set_input(preprocessed_data);
Expand Down
Loading

0 comments on commit 11d5e55

Please sign in to comment.