Skip to main content

Python wrapper for CONRAD (https://www5.cs.fau.de/conrad/), a framework for cone beam radiography

Project description

pyconrad

PyPI version Build Status https://codecov.io/gh/theHamsta/pyconrad/branch/master/graph/badge.svg

A python wrapper for the CONRAD framework (https://www5.cs.fau.de/conrad/)

CONRAD

CONRAD is a state-of-the-art software platform with extensive documentation. It is based on platform-independent technologies. Special libraries offer access to hardware acceleration such as CUDA and OpenCL. There is an easy interface for parallel processing. The software package includes different simulation tools that are able to generate 4-D projection and volume data and respective vector motion fields. Well known reconstruction algorithms such as FBP, DBP, and ART are included. All algorithms in the package are referenced to a scientific source. Please visit http://conrad.stanford.edu for more information.

Installation

Install via pip (vtk, opencl is optional):

pip install pyconrad[vtk,opencl]

or if you downloaded this repository (https://git5.cs.fau.de/PyConrad/pyCONRAD) using:

pip install -e .

This will automatically install CONRAD and all python dependencies. Requirements for proper functioning are at Python of version 3.6 or newer and Java 8.

If you encounter a problem during the installation have a look at our wiki: https://git5.cs.fau.de/PyConrad/pyCONRAD/wikis/home

Tests

If you want to test whether pyconrad is working correctly on your computer you may execute all tests included in this repo via:

python setup.py test

Changelog

Can be found CHANGELOG.md.

Usage

You can start CONRAD in Python like this:

import pyconrad

pyconrad.setup_pyconrad()
pyconrad.start_gui()  # start ImageJ
pyconrad.start_reconstruction_pipeline_gui() # if you want to start CONRAD's reconstruction filter pipeline

Or you can run CONRAD Reconstruction Pipeline from command line:

conrad
# or: conrad_imagej

ImageJ Commands

You can access all classes of ImageJ and Conrad after you initialized the JVM.

import pyconrad.autoinit
import ij
from edu.stanford.rsl.conrad.data.numeric import NumericGrid
import numpy as np

pyconrad.start_gui()

a = np.random.rand(20, 30)
grid = NumericGrid.from_numpy(a)
grid.show()

ij.IJ.run('FFT')

imshow

You can also use pyconrad to view NumPy arrays in ImageJ.

import pyconrad.autoinit
import numpy as np
import time

a = np.random.rand(20, 30)
luts = ['Fire', 'Spectrum', 'Ice', 'Cyan']

for lut in luts:
    pyconrad.imshow(a, lut, lut=lut)

print('Enjoy white noise!')
for i in range(300):
    noise = np.random.rand(200, 200)
    pyconrad.imshow(noise, 'White noise', spacing=(3, 2), origin=(0, 2))
    time.sleep(0.01)

pyconrad.close_all_windows()

Basic example

You can access CONRAD’s Java classes via pyconrad.edu() or using the convinience class ClassGetter.

import pyconrad.autoinit
import edu.stanford.rsl.tutorial.phantoms
from edu.stanford.rsl.conrad.phantom import NumericalSheppLogan3D

phantom2d = edu.stanford.rsl.tutorial.phantoms.MickeyMouseGrid2D(100, 100)
phantom3d = NumericalSheppLogan3D(
    100, 100, 100).getNumericalSheppLoganPhantom()

# You can also group Java packages an access all classes that are contained (import * does not work)
# Access more easily using ClassGetter (
_ = pyconrad.ClassGetter(
    'edu.stanford.rsl.tutorial.phantoms',
    'edu.stanford.rsl.conrad.phantom'
)

print('This is a Java class: ' + str(_.NumericalSheppLogan3D))

# Shape is for dimensions (z,y,x), size for (x,y,z)
print(grid.shape)
print(grid.size)

# Use Java method of class MickeyMouseGrid2D
phantom2d.show()
phantom3d.show()

Also memory transfers to numpy.ndarray are possible. Numeric grids have the additional methods from_numpy and as_numpy:

_ = pyconrad.ClassGetter()

array = np.random.rand(4, 2, 3).astype(pyconrad.java_float_dtype)
grid = _.NumericGrid.from_numpy(array)



# Manipulate data in using CONRAD at Position (x,y,z) = (0,1,3)
grid.setValue(5.0, [0, 1, 3])
# or easier with Python indices (reversed)
grid[3,1,0] = 5

# Shape
print(grid.shape)
print(grid.size)

# Get modified array
new_array = grid.as_numpy()

# Attention: Python has a different indexing (z,y,x)
print('Old value: %f' % array[3, 1, 0])
print('New value: %f' % new_array[3, 1, 0])

More Examples

More examples can be found here

Extension methods for java classes

For easy transition between Java and Python we extended some important Java classes in Python to convert between the respective Java class and the respective numpy structure. The following java classes are extended:

  • PointND

  • SimpleVector

  • SimpleMatrix

  • Numeric Grid(therefore all Grid1D - Grid4D)

with the methods:

  • as_numpy (array or matrix depending on the class representation)

  • from_numpy

  • from_list

  • from_tif

  • save_tif

  • save_vtk

Frequently encountered problems

# Creating a PointND
_.PointND(3,3)  # does not work
_.PointND([3,3])  # this does work
_.PointND(JArray(JDouble)([3,2]))  # works
_.PointND.from_numpy(np.array([2.1,3.1])) #works, uses extension method
_.PointND.from_list([2.1,3.1]) #works, uses extension method

# Getting PointND as numpy array
numpy_point = java_point.as_numpy()

# the same applies for SimpleVector
_.SimpleVector([3,2])  # does not work. pyconrad does not know whether you want to call SimpleVector(final double... otherBuffer) or public SimpleVector(final float... otherBuffer)
_.SimpleVector(JArray(JDouble)([3,2]))  # works
_.SimpleVector.from_numpy(np.array([2.1,3.1])) #works, uses extension method
_.SimpleVector.from_list([2.1,3.1]) #works, uses extension method

#Getting SimpleVector as numpy array
numpy_vector = java_vector.as_numpy()

#the same applies for SimpleMatrix
_.SimpleMatrix(JArray(JDouble,2)([[1.1,2.2,3.3],[4.4,5.5,6.6]]))  # works
_.SimpleMatrix.from_numpy(np.matrix([[1.1,2.2,3.3],[4.4,5.5,6.6]])) #works, uses extension method
_.SimpleMatrix.from_list([[1.1,2.2,3.3],[4.4,5.5,6.6]]) #works, uses extension method

#Getting SimpleMatrix as numpy matrix
numpy_matrix = java_matrix.as_numpy()

# Grid.setOrigin(...), setSpacing
_.Grid2D(3,2).setOrigin(JArray(JDouble)([2,3]))

# Creating nested enums
traj = _.HelicalTrajectory()
print(traj.getDetectorOffsetU())  # returns a float
enumval = _.['Projection$CameraAxisDirection'].values()[int(traj.getDetectorOffsetU())] # Convert back to enum
enumval = jvm.enumval_from_int('Projection$CameraAxisDirection', traj.getDetectorOffsetU())  # or like that

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyconrad-0.7.10.tar.gz (713.8 kB view details)

Uploaded Source

File details

Details for the file pyconrad-0.7.10.tar.gz.

File metadata

  • Download URL: pyconrad-0.7.10.tar.gz
  • Upload date:
  • Size: 713.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.39.0 CPython/3.8.6

File hashes

Hashes for pyconrad-0.7.10.tar.gz
Algorithm Hash digest
SHA256 d63bd3e4e5c6774958fab0fb2ad320627f6b01c2ea3d4dc37d30a4bc229626ae
MD5 6b4ea2a4b7a182e52a1dea7bf84ac0a3
BLAKE2b-256 137df3db0cb97d241e00105121672a6a5d51b0595702da0f389113cd4ead7892

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page