Package: pyconrad
pyconradA python wrapper for the CONRAD framework (https://www5.cs.fau.de/conrad/)CONRADCONRAD 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 visithttp://conrad.stanford.edufor more information.InstallationInstall via pip (vtk,openclis optional):pipinstallpyconrad[vtk,opencl]or if you downloaded this repository (https://git5.cs.fau.de/PyConrad/pyCONRAD) using:pipinstall-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/homeTestsIf you want to test whether pyconrad is working correctly on your computer you may execute all tests included in this repo via:pythonsetup.pytestChangelogCan be foundCHANGELOG.md.UsageYou can start CONRAD in Python like this:importpyconradpyconrad.setup_pyconrad()pyconrad.start_gui()# start ImageJpyconrad.start_reconstruction_pipeline_gui()# if you want to start CONRAD's reconstruction filter pipelineOr you can run CONRAD Reconstruction Pipeline from command line:conrad# or: conrad_imagejImageJ CommandsYou can access all classes of ImageJ and Conrad after you initialized the JVM.importpyconrad.autoinitimportijfromedu.stanford.rsl.conrad.data.numericimportNumericGridimportnumpyasnppyconrad.start_gui()a=np.random.rand(20,30)grid=NumericGrid.from_numpy(a)grid.show()ij.IJ.run('FFT')imshowYou can also usepyconradto view NumPy arrays in ImageJ.importpyconrad.autoinitimportnumpyasnpimporttimea=np.random.rand(20,30)luts=['Fire','Spectrum','Ice','Cyan']forlutinluts:pyconrad.imshow(a,lut,lut=lut)print('Enjoy white noise!')foriinrange(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 exampleYou can access CONRAD’s Java classes via pyconrad.edu() or using the convinience class ClassGetter.importpyconrad.autoinitimportedu.stanford.rsl.tutorial.phantomsfromedu.stanford.rsl.conrad.phantomimportNumericalSheppLogan3Dphantom2d=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 MickeyMouseGrid2Dphantom2d.show()phantom3d.show()Also memory transfers to numpy.ndarray are possible. Numeric grids have the additional methodsfrom_numpyandas_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# Shapeprint(grid.shape)print(grid.size)# Get modified arraynew_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 ExamplesMore examples can be foundhereExtension methods for java classesFor 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:PointNDSimpleVectorSimpleMatrixNumeric Grid(therefore all Grid1D - Grid4D)with the methods:as_numpy (array or matrix depending on the class representation)from_numpyfrom_listfrom_tifsave_tifsave_vtkFrequently 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 arraynumpy_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 arraynumpy_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 matrixnumpy_matrix=java_matrix.as_numpy()# Grid.setOrigin(...), setSpacing_.Grid2D(3,2).setOrigin(JArray(JDouble)([2,3]))# Creating nested enumstraj=_.HelicalTrajectory()print(traj.getDetectorOffsetU())# returns a floatenumval=_.['Projection$CameraAxisDirection'].values()[int(traj.getDetectorOffsetU())]# Convert back to enumenumval=jvm.enumval_from_int('Projection$CameraAxisDirection',traj.getDetectorOffsetU())# or like that