simind-python-connector 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- simind_python_connector/__init__.py +72 -0
- simind_python_connector/backends/__init__.py +480 -0
- simind_python_connector/backends/base.py +387 -0
- simind_python_connector/backends/sirf_backend.py +309 -0
- simind_python_connector/backends/stir_backend.py +395 -0
- simind_python_connector/builders/__init__.py +19 -0
- simind_python_connector/builders/acquisition_builder.py +526 -0
- simind_python_connector/builders/image_builder.py +217 -0
- simind_python_connector/configs/AnyScan.yaml +420 -0
- simind_python_connector/configs/Discovery670.yaml +412 -0
- simind_python_connector/configs/Example.yaml +420 -0
- simind_python_connector/configs/MLD001_SCAN0.yaml +426 -0
- simind_python_connector/configs/__init__.py +41 -0
- simind_python_connector/configs/input.smc +51 -0
- simind_python_connector/connectors/__init__.py +24 -0
- simind_python_connector/connectors/_spacing.py +69 -0
- simind_python_connector/connectors/base.py +40 -0
- simind_python_connector/connectors/python_connector.py +355 -0
- simind_python_connector/connectors/pytomography_adaptor.py +263 -0
- simind_python_connector/connectors/sirf_adaptor.py +164 -0
- simind_python_connector/connectors/stir_adaptor.py +164 -0
- simind_python_connector/converters/__init__.py +16 -0
- simind_python_connector/converters/attenuation.py +367 -0
- simind_python_connector/converters/dicom_to_stir.py +3 -0
- simind_python_connector/converters/simind_to_stir.py +769 -0
- simind_python_connector/core/__init__.py +7 -0
- simind_python_connector/core/config.py +939 -0
- simind_python_connector/core/executor.py +96 -0
- simind_python_connector/core/types.py +203 -0
- simind_python_connector/data/Schneider2000.json +222 -0
- simind_python_connector/data/__init__.py +25 -0
- simind_python_connector/data/bone.atn +187 -0
- simind_python_connector/data/h2o.atn +92 -0
- simind_python_connector/utils/__init__.py +120 -0
- simind_python_connector/utils/backend_access.py +121 -0
- simind_python_connector/utils/import_helpers.py +74 -0
- simind_python_connector/utils/interfile_numpy.py +195 -0
- simind_python_connector/utils/interfile_parser.py +175 -0
- simind_python_connector/utils/io_utils.py +14 -0
- simind_python_connector/utils/simind_utils.py +70 -0
- simind_python_connector/utils/sirf_stir_utils.py +194 -0
- simind_python_connector/utils/stir_utils.py +485 -0
- simind_python_connector-1.0.0.dist-info/METADATA +274 -0
- simind_python_connector-1.0.0.dist-info/RECORD +47 -0
- simind_python_connector-1.0.0.dist-info/WHEEL +5 -0
- simind_python_connector-1.0.0.dist-info/licenses/LICENSE +195 -0
- simind_python_connector-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<head><title>NIST XCOM database</title><!-- Google Analtyics 4 -->
|
|
2
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9SLN1VEEJ2"></script>
|
|
3
|
+
<script>
|
|
4
|
+
window.dataLayer = window.dataLayer || [];
|
|
5
|
+
function gtag(){dataLayer.push(arguments);}
|
|
6
|
+
gtag('js', new Date());
|
|
7
|
+
gtag('config', 'G-9SLN1VEEJ2');
|
|
8
|
+
</script>
|
|
9
|
+
<!-- End of Google Analytics 4 -->
|
|
10
|
+
<SCRIPT async type="text/javascript" id="_fed_an_ua_tag" src="https://dap.digitalgov.gov/Universal-Federated-Analytics-Min.js?agency=DOC&subagency=NIST&pua=UA-37115410-46&yt=false&exts=ppsx,pps,f90,sch,rtf,wrl,txz,m1v,xlsm,msi,xsd,f,tif,eps,mpg,xml,pl,xlt,c"></script></head>Photon
|
|
11
|
+
Energy Coherent
|
|
12
|
+
|
|
13
|
+
1.000E-03 3.442E+03
|
|
14
|
+
1.000E-03 3.442E+03
|
|
15
|
+
1.305E-03 1.689E+03
|
|
16
|
+
1.305E-03 1.699E+03
|
|
17
|
+
1.500E-03 1.166E+03
|
|
18
|
+
2.000E-03 5.253E+02
|
|
19
|
+
2.145E-03 4.310E+02
|
|
20
|
+
2.145E-03 5.867E+02
|
|
21
|
+
2.303E-03 4.854E+02
|
|
22
|
+
2.472E-03 4.014E+02
|
|
23
|
+
2.472E-03 4.051E+02
|
|
24
|
+
3.000E-03 2.397E+02
|
|
25
|
+
4.000E-03 1.068E+02
|
|
26
|
+
4.038E-03 1.040E+02
|
|
27
|
+
4.038E-03 2.370E+02
|
|
28
|
+
5.000E-03 1.354E+02
|
|
29
|
+
6.000E-03 8.246E+01
|
|
30
|
+
7.000E-03 5.396E+01
|
|
31
|
+
8.000E-03 3.728E+01
|
|
32
|
+
9.000E-03 2.682E+01
|
|
33
|
+
1.000E-02 1.993E+01
|
|
34
|
+
1.100E-02 1.522E+01
|
|
35
|
+
1.200E-02 1.190E+01
|
|
36
|
+
1.300E-02 9.482E+00
|
|
37
|
+
1.400E-02 7.687E+00
|
|
38
|
+
1.500E-02 6.325E+00
|
|
39
|
+
1.600E-02 5.273E+00
|
|
40
|
+
1.700E-02 4.447E+00
|
|
41
|
+
1.800E-02 3.791E+00
|
|
42
|
+
1.900E-02 3.262E+00
|
|
43
|
+
2.000E-02 2.832E+00
|
|
44
|
+
2.100E-02 2.477E+00
|
|
45
|
+
2.200E-02 2.184E+00
|
|
46
|
+
2.300E-02 1.938E+00
|
|
47
|
+
2.400E-02 1.731E+00
|
|
48
|
+
2.500E-02 1.555E+00
|
|
49
|
+
2.600E-02 1.404E+00
|
|
50
|
+
2.700E-02 1.275E+00
|
|
51
|
+
2.800E-02 1.164E+00
|
|
52
|
+
2.900E-02 1.067E+00
|
|
53
|
+
3.000E-02 9.820E-01
|
|
54
|
+
3.100E-02 9.078E-01
|
|
55
|
+
3.200E-02 8.424E-01
|
|
56
|
+
3.300E-02 7.847E-01
|
|
57
|
+
3.400E-02 7.334E-01
|
|
58
|
+
3.500E-02 6.877E-01
|
|
59
|
+
3.600E-02 6.468E-01
|
|
60
|
+
3.700E-02 6.102E-01
|
|
61
|
+
3.800E-02 5.773E-01
|
|
62
|
+
3.900E-02 5.476E-01
|
|
63
|
+
4.000E-02 5.207E-01
|
|
64
|
+
4.100E-02 4.963E-01
|
|
65
|
+
4.200E-02 4.742E-01
|
|
66
|
+
4.300E-02 4.540E-01
|
|
67
|
+
4.400E-02 4.355E-01
|
|
68
|
+
4.500E-02 4.186E-01
|
|
69
|
+
4.600E-02 4.031E-01
|
|
70
|
+
4.700E-02 3.889E-01
|
|
71
|
+
4.800E-02 3.757E-01
|
|
72
|
+
4.900E-02 3.636E-01
|
|
73
|
+
5.000E-02 3.524E-01
|
|
74
|
+
5.100E-02 3.420E-01
|
|
75
|
+
5.200E-02 3.323E-01
|
|
76
|
+
5.300E-02 3.234E-01
|
|
77
|
+
5.400E-02 3.150E-01
|
|
78
|
+
5.500E-02 3.072E-01
|
|
79
|
+
5.600E-02 3.000E-01
|
|
80
|
+
5.700E-02 2.932E-01
|
|
81
|
+
5.800E-02 2.868E-01
|
|
82
|
+
5.900E-02 2.808E-01
|
|
83
|
+
6.000E-02 2.752E-01
|
|
84
|
+
6.100E-02 2.699E-01
|
|
85
|
+
6.200E-02 2.649E-01
|
|
86
|
+
6.300E-02 2.603E-01
|
|
87
|
+
6.400E-02 2.558E-01
|
|
88
|
+
6.500E-02 2.516E-01
|
|
89
|
+
6.600E-02 2.477E-01
|
|
90
|
+
6.700E-02 2.439E-01
|
|
91
|
+
6.800E-02 2.403E-01
|
|
92
|
+
6.900E-02 2.370E-01
|
|
93
|
+
7.000E-02 2.337E-01
|
|
94
|
+
7.100E-02 2.307E-01
|
|
95
|
+
7.200E-02 2.278E-01
|
|
96
|
+
7.300E-02 2.250E-01
|
|
97
|
+
7.400E-02 2.223E-01
|
|
98
|
+
7.500E-02 2.198E-01
|
|
99
|
+
7.600E-02 2.174E-01
|
|
100
|
+
7.700E-02 2.151E-01
|
|
101
|
+
7.800E-02 2.129E-01
|
|
102
|
+
7.900E-02 2.107E-01
|
|
103
|
+
8.000E-02 2.087E-01
|
|
104
|
+
8.100E-02 2.067E-01
|
|
105
|
+
8.200E-02 2.049E-01
|
|
106
|
+
8.300E-02 2.030E-01
|
|
107
|
+
8.400E-02 2.013E-01
|
|
108
|
+
8.500E-02 1.996E-01
|
|
109
|
+
8.600E-02 1.980E-01
|
|
110
|
+
8.700E-02 1.965E-01
|
|
111
|
+
8.800E-02 1.949E-01
|
|
112
|
+
8.900E-02 1.935E-01
|
|
113
|
+
9.000E-02 1.921E-01
|
|
114
|
+
9.100E-02 1.907E-01
|
|
115
|
+
9.200E-02 1.894E-01
|
|
116
|
+
9.300E-02 1.881E-01
|
|
117
|
+
9.400E-02 1.869E-01
|
|
118
|
+
9.500E-02 1.857E-01
|
|
119
|
+
9.600E-02 1.846E-01
|
|
120
|
+
9.700E-02 1.834E-01
|
|
121
|
+
9.800E-02 1.823E-01
|
|
122
|
+
9.900E-02 1.813E-01
|
|
123
|
+
1.000E-01 1.802E-01
|
|
124
|
+
1.500E-01 1.491E-01
|
|
125
|
+
2.000E-01 1.332E-01
|
|
126
|
+
3.000E-01 1.141E-01
|
|
127
|
+
4.000E-01 1.018E-01
|
|
128
|
+
5.000E-01 9.275E-02
|
|
129
|
+
6.000E-01 8.570E-02
|
|
130
|
+
8.000E-01 7.520E-02
|
|
131
|
+
1.000E+00 6.758E-02
|
|
132
|
+
1.022E+00 6.687E-02
|
|
133
|
+
1.250E+00 6.043E-02
|
|
134
|
+
1.500E+00 5.501E-02
|
|
135
|
+
2.000E+00 4.733E-02
|
|
136
|
+
2.044E+00 4.678E-02
|
|
137
|
+
3.000E+00 3.826E-02
|
|
138
|
+
4.000E+00 3.307E-02
|
|
139
|
+
5.000E+00 2.971E-02
|
|
140
|
+
6.000E+00 2.738E-02
|
|
141
|
+
7.000E+00 2.568E-02
|
|
142
|
+
8.000E+00 2.440E-02
|
|
143
|
+
9.000E+00 2.341E-02
|
|
144
|
+
1.000E+01 2.263E-02
|
|
145
|
+
1.100E+01 2.200E-02
|
|
146
|
+
1.200E+01 2.148E-02
|
|
147
|
+
1.300E+01 2.105E-02
|
|
148
|
+
1.400E+01 2.069E-02
|
|
149
|
+
1.500E+01 2.040E-02
|
|
150
|
+
1.600E+01 2.015E-02
|
|
151
|
+
1.800E+01 1.976E-02
|
|
152
|
+
2.000E+01 1.948E-02
|
|
153
|
+
2.200E+01 1.928E-02
|
|
154
|
+
2.400E+01 1.914E-02
|
|
155
|
+
2.600E+01 1.904E-02
|
|
156
|
+
2.800E+01 1.897E-02
|
|
157
|
+
3.000E+01 1.892E-02
|
|
158
|
+
4.000E+01 1.892E-02
|
|
159
|
+
5.000E+01 1.908E-02
|
|
160
|
+
6.000E+01 1.930E-02
|
|
161
|
+
8.000E+01 1.975E-02
|
|
162
|
+
1.000E+02 2.016E-02
|
|
163
|
+
1.500E+02 2.099E-02
|
|
164
|
+
2.000E+02 2.157E-02
|
|
165
|
+
3.000E+02 2.233E-02
|
|
166
|
+
4.000E+02 2.282E-02
|
|
167
|
+
5.000E+02 2.315E-02
|
|
168
|
+
6.000E+02 2.340E-02
|
|
169
|
+
8.000E+02 2.374E-02
|
|
170
|
+
1.000E+03 2.397E-02
|
|
171
|
+
1.500E+03 2.431E-02
|
|
172
|
+
2.000E+03 2.450E-02
|
|
173
|
+
3.000E+03 2.471E-02
|
|
174
|
+
4.000E+03 2.483E-02
|
|
175
|
+
5.000E+03 2.490E-02
|
|
176
|
+
6.000E+03 2.496E-02
|
|
177
|
+
8.000E+03 2.503E-02
|
|
178
|
+
1.000E+04 2.507E-02
|
|
179
|
+
1.500E+04 2.513E-02
|
|
180
|
+
2.000E+04 2.517E-02
|
|
181
|
+
3.000E+04 2.520E-02
|
|
182
|
+
4.000E+04 2.522E-02
|
|
183
|
+
5.000E+04 2.523E-02
|
|
184
|
+
6.000E+04 2.524E-02
|
|
185
|
+
8.000E+04 2.525E-02
|
|
186
|
+
1.000E+05 2.526E-02
|
|
187
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<head><title>NIST XCOM database</title><!-- Google Analtyics 4 -->
|
|
2
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9SLN1VEEJ2"></script>
|
|
3
|
+
<script>
|
|
4
|
+
window.dataLayer = window.dataLayer || [];
|
|
5
|
+
function gtag(){dataLayer.push(arguments);}
|
|
6
|
+
gtag('js', new Date());
|
|
7
|
+
gtag('config', 'G-9SLN1VEEJ2');
|
|
8
|
+
</script>
|
|
9
|
+
<!-- End of Google Analytics 4 -->
|
|
10
|
+
<SCRIPT async type="text/javascript" id="_fed_an_ua_tag" src="https://dap.digitalgov.gov/Universal-Federated-Analytics-Min.js?agency=DOC&subagency=NIST&pua=UA-37115410-46&yt=false&exts=ppsx,pps,f90,sch,rtf,wrl,txz,m1v,xlsm,msi,xsd,f,tif,eps,mpg,xml,pl,xlt,c"></script></head>Photon Tot. w/
|
|
11
|
+
Energy Coherent
|
|
12
|
+
|
|
13
|
+
1.000E-03 4.077E+03
|
|
14
|
+
1.500E-03 1.376E+03
|
|
15
|
+
2.000E-03 6.173E+02
|
|
16
|
+
3.000E-03 1.928E+02
|
|
17
|
+
4.000E-03 8.277E+01
|
|
18
|
+
5.000E-03 4.259E+01
|
|
19
|
+
6.000E-03 2.464E+01
|
|
20
|
+
8.000E-03 1.037E+01
|
|
21
|
+
1.000E-02 5.330E+00
|
|
22
|
+
1.500E-02 1.672E+00
|
|
23
|
+
2.000E-02 8.098E-01
|
|
24
|
+
3.000E-02 3.756E-01
|
|
25
|
+
4.000E-02 2.683E-01
|
|
26
|
+
5.000E-02 2.269E-01
|
|
27
|
+
6.000E-02 2.059E-01
|
|
28
|
+
8.000E-02 1.837E-01
|
|
29
|
+
1.000E-01 1.707E-01
|
|
30
|
+
1.500E-01 1.505E-01
|
|
31
|
+
2.000E-01 1.370E-01
|
|
32
|
+
3.000E-01 1.186E-01
|
|
33
|
+
4.000E-01 1.061E-01
|
|
34
|
+
5.000E-01 9.687E-02
|
|
35
|
+
6.000E-01 8.956E-02
|
|
36
|
+
8.000E-01 7.866E-02
|
|
37
|
+
1.000E+00 7.072E-02
|
|
38
|
+
1.022E+00 6.997E-02
|
|
39
|
+
1.250E+00 6.323E-02
|
|
40
|
+
1.500E+00 5.754E-02
|
|
41
|
+
2.000E+00 4.942E-02
|
|
42
|
+
2.044E+00 4.883E-02
|
|
43
|
+
3.000E+00 3.969E-02
|
|
44
|
+
4.000E+00 3.403E-02
|
|
45
|
+
5.000E+00 3.031E-02
|
|
46
|
+
6.000E+00 2.770E-02
|
|
47
|
+
7.000E+00 2.577E-02
|
|
48
|
+
8.000E+00 2.429E-02
|
|
49
|
+
9.000E+00 2.313E-02
|
|
50
|
+
1.000E+01 2.219E-02
|
|
51
|
+
1.100E+01 2.142E-02
|
|
52
|
+
1.200E+01 2.079E-02
|
|
53
|
+
1.300E+01 2.025E-02
|
|
54
|
+
1.400E+01 1.980E-02
|
|
55
|
+
1.500E+01 1.941E-02
|
|
56
|
+
1.600E+01 1.908E-02
|
|
57
|
+
1.800E+01 1.854E-02
|
|
58
|
+
2.000E+01 1.813E-02
|
|
59
|
+
2.200E+01 1.782E-02
|
|
60
|
+
2.400E+01 1.757E-02
|
|
61
|
+
2.600E+01 1.738E-02
|
|
62
|
+
2.800E+01 1.722E-02
|
|
63
|
+
3.000E+01 1.710E-02
|
|
64
|
+
4.000E+01 1.679E-02
|
|
65
|
+
5.000E+01 1.674E-02
|
|
66
|
+
6.000E+01 1.679E-02
|
|
67
|
+
8.000E+01 1.702E-02
|
|
68
|
+
1.000E+02 1.727E-02
|
|
69
|
+
1.500E+02 1.785E-02
|
|
70
|
+
2.000E+02 1.829E-02
|
|
71
|
+
3.000E+02 1.888E-02
|
|
72
|
+
4.000E+02 1.927E-02
|
|
73
|
+
5.000E+02 1.954E-02
|
|
74
|
+
6.000E+02 1.974E-02
|
|
75
|
+
8.000E+02 2.002E-02
|
|
76
|
+
1.000E+03 2.020E-02
|
|
77
|
+
1.500E+03 2.048E-02
|
|
78
|
+
2.000E+03 2.064E-02
|
|
79
|
+
3.000E+03 2.082E-02
|
|
80
|
+
4.000E+03 2.091E-02
|
|
81
|
+
5.000E+03 2.097E-02
|
|
82
|
+
6.000E+03 2.102E-02
|
|
83
|
+
8.000E+03 2.108E-02
|
|
84
|
+
1.000E+04 2.111E-02
|
|
85
|
+
1.500E+04 2.117E-02
|
|
86
|
+
2.000E+04 2.120E-02
|
|
87
|
+
3.000E+04 2.123E-02
|
|
88
|
+
4.000E+04 2.124E-02
|
|
89
|
+
5.000E+04 2.125E-02
|
|
90
|
+
6.000E+04 2.126E-02
|
|
91
|
+
8.000E+04 2.127E-02
|
|
92
|
+
1.000E+05 2.127E-02
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Grab-bag of general utilities shared across modules.
|
|
3
|
+
They are re-exported here for a single, easy import path.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import contextlib
|
|
7
|
+
import importlib
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Lazy imports to avoid SIRF dependencies in CI
|
|
11
|
+
def __getattr__(name):
|
|
12
|
+
if name in (
|
|
13
|
+
"interfile_numpy",
|
|
14
|
+
"io_utils",
|
|
15
|
+
"simind_utils",
|
|
16
|
+
"stir_utils",
|
|
17
|
+
"sirf_stir_utils",
|
|
18
|
+
):
|
|
19
|
+
return importlib.import_module(f".{name}", __name__)
|
|
20
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_array(obj):
|
|
24
|
+
"""Return NumPy array from SIRF or STIR object.
|
|
25
|
+
|
|
26
|
+
This function works with both SIRF and STIR Python backends:
|
|
27
|
+
- SIRF: Uses .asarray() or .as_array()
|
|
28
|
+
- STIR: Uses stirextra.to_numpy()
|
|
29
|
+
- Backend wrappers: Uses .as_array() method
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
obj: Image or acquisition data object (SIRF, STIR, or wrapped)
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
np.ndarray: NumPy array view of the data
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
AttributeError: If object cannot be converted to array
|
|
39
|
+
"""
|
|
40
|
+
# Check if it's a wrapped backend object
|
|
41
|
+
if hasattr(obj, "as_array") and callable(obj.as_array):
|
|
42
|
+
return obj.as_array()
|
|
43
|
+
|
|
44
|
+
# Try SIRF native methods
|
|
45
|
+
if hasattr(obj, "asarray"):
|
|
46
|
+
try:
|
|
47
|
+
return obj.asarray()
|
|
48
|
+
except Exception:
|
|
49
|
+
return obj.as_array() # Fallback to as_array if asarray fails
|
|
50
|
+
if hasattr(obj, "as_array"):
|
|
51
|
+
return obj.as_array()
|
|
52
|
+
|
|
53
|
+
# Try STIR native conversion
|
|
54
|
+
with contextlib.suppress(ImportError, TypeError, AttributeError):
|
|
55
|
+
import stirextra
|
|
56
|
+
|
|
57
|
+
return stirextra.to_numpy(obj)
|
|
58
|
+
raise AttributeError(
|
|
59
|
+
f"Cannot convert {type(obj)} to numpy array. "
|
|
60
|
+
f"Object must have asarray(), as_array() method, or be a STIR object."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def to_projdata_in_memory(proj_data):
|
|
65
|
+
"""Convert ProjData to ProjDataInMemory for arithmetic operations.
|
|
66
|
+
|
|
67
|
+
STIR's ProjData objects don't support arithmetic operations directly.
|
|
68
|
+
This function converts them to ProjDataInMemory which does.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
proj_data: STIR ProjData object or SIRF AcquisitionData
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
ProjDataInMemory object (STIR) or cloned AcquisitionData (SIRF)
|
|
75
|
+
|
|
76
|
+
Note:
|
|
77
|
+
For SIRF AcquisitionData, this returns a clone since SIRF already
|
|
78
|
+
supports arithmetic operations.
|
|
79
|
+
"""
|
|
80
|
+
# Check if it's SIRF (has clone method and supports arithmetic)
|
|
81
|
+
if hasattr(proj_data, "clone") and not hasattr(proj_data, "get_proj_data_info"):
|
|
82
|
+
return proj_data.clone()
|
|
83
|
+
|
|
84
|
+
# STIR backend: convert to ProjDataInMemory
|
|
85
|
+
try:
|
|
86
|
+
import stir
|
|
87
|
+
|
|
88
|
+
# Check if already ProjDataInMemory
|
|
89
|
+
if isinstance(proj_data, stir.ProjDataInMemory):
|
|
90
|
+
return proj_data
|
|
91
|
+
|
|
92
|
+
# Convert ProjData to ProjDataInMemory
|
|
93
|
+
proj_data_in_mem = stir.ProjDataInMemory(
|
|
94
|
+
proj_data.get_exam_info(), proj_data.get_proj_data_info()
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Copy data segment by segment
|
|
98
|
+
for seg_num in range(
|
|
99
|
+
proj_data.get_min_segment_num(), proj_data.get_max_segment_num() + 1
|
|
100
|
+
):
|
|
101
|
+
seg = proj_data.get_segment_by_sinogram(seg_num)
|
|
102
|
+
proj_data_in_mem.set_segment(seg)
|
|
103
|
+
|
|
104
|
+
return proj_data_in_mem
|
|
105
|
+
except ImportError:
|
|
106
|
+
# Neither SIRF nor STIR available - return original
|
|
107
|
+
return proj_data
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
__all__ = [
|
|
111
|
+
"get_array",
|
|
112
|
+
"interfile_numpy",
|
|
113
|
+
"to_projdata_in_memory",
|
|
114
|
+
"io_utils",
|
|
115
|
+
"simind_utils",
|
|
116
|
+
"stir_utils",
|
|
117
|
+
"sirf_stir_utils",
|
|
118
|
+
"step_size_rules",
|
|
119
|
+
"cil_partitioner",
|
|
120
|
+
]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Centralized backend import and access helpers.
|
|
3
|
+
|
|
4
|
+
This module provides a single source of truth for backend imports, eliminating
|
|
5
|
+
the need for duplicate try/except import blocks scattered throughout the codebase.
|
|
6
|
+
|
|
7
|
+
All backend-related imports (factory functions, interfaces, detection utilities,
|
|
8
|
+
and wrappers) are centralized here, with proper fallback handling when backends
|
|
9
|
+
are unavailable.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from types import SimpleNamespace
|
|
13
|
+
from typing import Any, Dict
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_backend_interfaces() -> tuple[bool, Dict[str, Any]]:
|
|
17
|
+
"""Get all backend interfaces and utilities with fallback handling.
|
|
18
|
+
|
|
19
|
+
This is the single source of truth for backend imports. When backends are
|
|
20
|
+
unavailable, it returns stub values (None or type(None)) so calling code
|
|
21
|
+
can check BACKEND_AVAILABLE and handle the missing dependencies gracefully.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
Tuple of (BACKEND_AVAILABLE, interfaces_dict) where interfaces_dict contains:
|
|
25
|
+
- 'factories': Backend factory functions
|
|
26
|
+
(create_acquisition_data, create_image_data)
|
|
27
|
+
- 'types': Interface type hints (AcquisitionDataInterface, ImageDataInterface)
|
|
28
|
+
- 'wrappers': Wrapping utilities
|
|
29
|
+
(ensure_acquisition_interface, ensure_image_interface, etc.)
|
|
30
|
+
- 'detection': Backend detection functions (detect_*_backend, get/set_backend)
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
>>> BACKEND_AVAILABLE, backends = get_backend_interfaces()
|
|
34
|
+
>>> if BACKEND_AVAILABLE:
|
|
35
|
+
>>> create_acq = backends['factories']['create_acquisition_data']
|
|
36
|
+
>>> data = create_acq('template.hs')
|
|
37
|
+
"""
|
|
38
|
+
try:
|
|
39
|
+
from simind_python_connector.backends import (
|
|
40
|
+
AcquisitionDataInterface,
|
|
41
|
+
ImageDataInterface,
|
|
42
|
+
create_acquisition_data,
|
|
43
|
+
create_image_data,
|
|
44
|
+
detect_acquisition_backend,
|
|
45
|
+
detect_backend_from_interface,
|
|
46
|
+
detect_image_backend,
|
|
47
|
+
get_backend,
|
|
48
|
+
set_backend,
|
|
49
|
+
)
|
|
50
|
+
from simind_python_connector.utils.sirf_stir_utils import (
|
|
51
|
+
ensure_acquisition_interface,
|
|
52
|
+
ensure_image_interface,
|
|
53
|
+
to_native_acquisition,
|
|
54
|
+
to_native_image,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return True, {
|
|
58
|
+
"factories": {
|
|
59
|
+
"create_acquisition_data": create_acquisition_data,
|
|
60
|
+
"create_image_data": create_image_data,
|
|
61
|
+
},
|
|
62
|
+
"types": {
|
|
63
|
+
"AcquisitionDataInterface": AcquisitionDataInterface,
|
|
64
|
+
"ImageDataInterface": ImageDataInterface,
|
|
65
|
+
},
|
|
66
|
+
"wrappers": {
|
|
67
|
+
"ensure_acquisition_interface": ensure_acquisition_interface,
|
|
68
|
+
"ensure_image_interface": ensure_image_interface,
|
|
69
|
+
"to_native_acquisition": to_native_acquisition,
|
|
70
|
+
"to_native_image": to_native_image,
|
|
71
|
+
},
|
|
72
|
+
"detection": {
|
|
73
|
+
"detect_acquisition_backend": detect_acquisition_backend,
|
|
74
|
+
"detect_image_backend": detect_image_backend,
|
|
75
|
+
"detect_backend_from_interface": detect_backend_from_interface,
|
|
76
|
+
"get_backend": get_backend,
|
|
77
|
+
"set_backend": set_backend,
|
|
78
|
+
},
|
|
79
|
+
}
|
|
80
|
+
except ImportError:
|
|
81
|
+
# Return fallback stubs when backends are unavailable
|
|
82
|
+
return False, {
|
|
83
|
+
"factories": {
|
|
84
|
+
"create_acquisition_data": None,
|
|
85
|
+
"create_image_data": None,
|
|
86
|
+
},
|
|
87
|
+
"types": {
|
|
88
|
+
"AcquisitionDataInterface": type(None),
|
|
89
|
+
"ImageDataInterface": type(None),
|
|
90
|
+
},
|
|
91
|
+
"wrappers": {
|
|
92
|
+
"ensure_acquisition_interface": None,
|
|
93
|
+
"ensure_image_interface": None,
|
|
94
|
+
"to_native_acquisition": None,
|
|
95
|
+
"to_native_image": None,
|
|
96
|
+
},
|
|
97
|
+
"detection": {
|
|
98
|
+
"detect_acquisition_backend": None,
|
|
99
|
+
"detect_image_backend": None,
|
|
100
|
+
"detect_backend_from_interface": None,
|
|
101
|
+
"get_backend": None,
|
|
102
|
+
"set_backend": None,
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _to_namespace(mapping: Dict[str, Any]) -> SimpleNamespace:
|
|
108
|
+
"""Convert a dictionary to a SimpleNamespace (handles None gracefully)."""
|
|
109
|
+
return SimpleNamespace(**(mapping or {}))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
BACKEND_AVAILABLE, _interfaces = get_backend_interfaces()
|
|
113
|
+
BACKENDS = SimpleNamespace(
|
|
114
|
+
factories=_to_namespace(_interfaces.get("factories", {})),
|
|
115
|
+
types=_to_namespace(_interfaces.get("types", {})),
|
|
116
|
+
wrappers=_to_namespace(_interfaces.get("wrappers", {})),
|
|
117
|
+
detection=_to_namespace(_interfaces.get("detection", {})),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
__all__ = ["get_backend_interfaces", "BACKEND_AVAILABLE", "BACKENDS"]
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Centralized import helpers for SIRF/STIR backends.
|
|
3
|
+
|
|
4
|
+
This module provides reusable functions for importing backend types with
|
|
5
|
+
proper fallback handling. This eliminates the need for duplicate try/except
|
|
6
|
+
import blocks scattered throughout the codebase.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Tuple, Type
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_sirf_types() -> Tuple[Type, Type, bool]:
|
|
13
|
+
"""Import SIRF types with fallback.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
Tuple of (ImageData, AcquisitionData, SIRF_AVAILABLE)
|
|
17
|
+
If SIRF is not available, returns (type(None), type(None), False)
|
|
18
|
+
"""
|
|
19
|
+
try:
|
|
20
|
+
from sirf.STIR import AcquisitionData, ImageData
|
|
21
|
+
|
|
22
|
+
return ImageData, AcquisitionData, True
|
|
23
|
+
except ImportError:
|
|
24
|
+
return type(None), type(None), False
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_stir_types() -> Tuple[Type, Type, bool]:
|
|
28
|
+
"""Import STIR Python types with fallback.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Tuple of (FloatVoxelsOnCartesianGrid, ProjData, STIR_AVAILABLE)
|
|
32
|
+
If STIR is not available, returns (type(None), type(None), False)
|
|
33
|
+
"""
|
|
34
|
+
try:
|
|
35
|
+
import stir
|
|
36
|
+
|
|
37
|
+
return stir.FloatVoxelsOnCartesianGrid, stir.ProjData, True
|
|
38
|
+
except ImportError:
|
|
39
|
+
return type(None), type(None), False
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_backend_types() -> Tuple[Type, Type, Type, Type, str]:
|
|
43
|
+
"""Import backend-agnostic types (tries SIRF first, then STIR).
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Tuple of (ImageData, AcquisitionData, ImageType, AcqType, backend_name)
|
|
47
|
+
where ImageType/AcqType are the native backend types
|
|
48
|
+
|
|
49
|
+
Raises:
|
|
50
|
+
ImportError: If neither SIRF nor STIR is available
|
|
51
|
+
"""
|
|
52
|
+
# Try SIRF first
|
|
53
|
+
ImageData, AcquisitionData, sirf_available = get_sirf_types()
|
|
54
|
+
if sirf_available:
|
|
55
|
+
return ImageData, AcquisitionData, ImageData, AcquisitionData, "sirf"
|
|
56
|
+
|
|
57
|
+
# Fall back to STIR
|
|
58
|
+
StirImage, StirProj, stir_available = get_stir_types()
|
|
59
|
+
if stir_available:
|
|
60
|
+
return StirImage, StirProj, StirImage, StirProj, "stir"
|
|
61
|
+
|
|
62
|
+
raise ImportError(
|
|
63
|
+
"Neither SIRF nor STIR Python is available. "
|
|
64
|
+
"Please install one of:\n"
|
|
65
|
+
" - SIRF (sirf.STIR)\n"
|
|
66
|
+
" - STIR Python (stir + stirextra)"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
__all__ = [
|
|
71
|
+
"get_sirf_types",
|
|
72
|
+
"get_stir_types",
|
|
73
|
+
"get_backend_types",
|
|
74
|
+
]
|