1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
from cil.framework import DataProcessor, AcquisitionData, DataOrder
import gi
gi.require_version('Ufo', '0.0')
from gi.repository import Ufo
import numpy as np
class UfoStandardForwardProjector(DataProcessor):
def __init__(self,
volume_geometry=None,
sinogram_geometry=None):
kwargs = {
'volume_geometry': volume_geometry,
'sinogram_geometry': sinogram_geometry
}
super(UfoStandardForwardProjector, self).__init__(**kwargs)
self.set_ImageGeometry(volume_geometry)
self.set_AcquisitionGeometry(sinogram_geometry)
def check_input(self, dataset):
if self.volume_geometry.shape != dataset.geometry.shape:
raise ValueError("Dataset not compatible with geometry used to create the projector")
return True
def set_ImageGeometry(self, volume_geometry):
DataOrder.check_order_for_engine('astra', volume_geometry)
if len(volume_geometry.dimension_labels) > 3:
raise ValueError("Supports 2D and 3D data only, got {0}".format(volume_geometry.number_of_dimensions))
self.volume_geometry = volume_geometry.copy()
def set_AcquisitionGeometry(self, sinogram_geometry):
DataOrder.check_order_for_engine('astra', sinogram_geometry)
if len(sinogram_geometry.dimension_labels) > 3:
raise ValueError("Supports 2D and 3D data only, got {0}".format(self.volume_geometry.number_of_dimensions))
self.sinogram_geometry = sinogram_geometry.copy()
def process(self, out=None):
IM = self.get_input()
data_temp = IM.as_array()
arr_out = self.create_sinogram(data_temp, out)
if out is None:
out = AcquisitionData(arr_out, deep_copy=False, geometry=self.sinogram_geometry.copy(),suppress_warning=True)
return out
else:
out.fill(arr_out)
def create_sinogram(self, vol, sino):
pm = Ufo.PluginManager()
graph = Ufo.TaskGraph()
scheduler = Ufo.Scheduler()
read = pm.get_task('memory-in')
read.props.pointer = vol.__array_interface__['data'][0]
read.props.width = vol.shape[1]
read.props.height = vol.shape[0]
if(len(vol.shape) == 2):
read.props.number = 1
else:
read.props.number = vol.shape[2]
read.props.bitdepth = 32
forwardproject = pm.get_task('forwardproject')
forwardproject.props.number = vol.shape[0]
sino_arr = np.zeros(self.sinogram_geometry.shape, dtype=np.float32)
write = pm.get_task('memory-out')
write.props.pointer = sino_arr.__array_interface__['data'][0]
write.props.max_size = sino_arr.nbytes
graph.connect_nodes(read, forwardproject)
graph.connect_nodes(forwardproject, write)
scheduler.run(graph)
return sino_arr
|