@@ -6,28 +6,41 @@ export parker_weight
66using LazyGrids: ndgrid
77
88
9- # parallel-beam case: returns a Vector
9+ """
10+ parker_weight(sg::SinoGeom ; T = Float32)
11+ Compute Parker weighting for non-360° orbits.
12+ See http://doi.org/10.1118/1.595078.
13+ Returns `Matrix{T}` of size:
14+ - (1,1) for `SinoPar` with typical 180 or 360 orbit
15+ - (1,na) for `SinoPar` with atypical orbit
16+ - (1,1) for `SinoFan` with typical 360 orbit
17+ - (ns,na) for `SinoFan` with typical 360 orbit
18+ """
19+ parker_weight
20+
21+
22+ # parallel-beam case
1023function parker_weight_par (
1124 orbit:: RealU ,
1225 ad:: AbstractVector{<:RealU} , # angles in degrees: sg.ad - sg.orbit_start
1326 ;
1427 T:: Type{<:Real} = Float32,
1528)
1629
17- wt = ones (T, length (ad))
18-
1930 if (orbit ÷ 180 ) * 180 == orbit
20- return wt # no weighting needed
31+ return ones (T, 1 , 1 ) # no weighting needed
2132 end
2233
23- if orbit < 180
34+ if abs ( orbit) < 180
2435 @warn (" orbit $orbit < 180" )
25- return wt # nonuniform weighting would not help
36+ return ones (T, 1 , 1 ) # nonuniform weighting would not help
2637 end
2738
39+ orbit = abs (orbit)
2840 orbit > 360 && error (" only 180 ≤ |orbit| ≤ 360 supported for Parker weighting" )
2941 extra = orbit - 180 # extra beyond 180
3042
43+ wt = ones (T, 1 , length (ad)) # (1,na)
3144 ad = abs .(ad)
3245 ii = ad .< extra
3346 @. wt[ii] = abs2 (sin (ad[ii] / extra * π/ 2 ))
@@ -38,17 +51,11 @@ function parker_weight_par(
3851end
3952
4053
41- """
42- parker_weight(sg::SinoGeom ; T = Float32)
43- Compute Parker weighting for non-360° orbits.
44- Returns `Vector{T}` of length `sg.na` for `SinoPar`.
45- Returns `Matrix{T}` of size `dims(sg)` for `SinoFan`.
46- """
47- parker_weight (sg:: SinoPar ; T:: Type{<:Real} = Float32):: Vector{T} =
54+ parker_weight (sg:: SinoPar ; T:: Type{<:Real} = Float32):: Matrix{T} =
4855 parker_weight_par (sg. orbit, sg. ad .- sg. orbit_start ; T)
4956
5057
51- function parker_weight_fan (
58+ function parker_weight_fan_short (
5259 nb:: Int ,
5360 na:: Int ,
5461 orbit:: RealU ,
@@ -65,7 +72,7 @@ function parker_weight_fan(
6572 @warn (" orbit $orbit is less than a short scan $orbit_short " )
6673
6774 orbit > orbit_short + rad2deg (ar[2 ] - ar[1 ]) &&
68- @warn (" orbit $orbit exeeds short scan $orbit_short by %g views" )
75+ @warn (" orbit $orbit exceeds short scan $orbit_short by %g views" )
6976 # (orbit - orbit_short) / rad2deg(ar[2] - ar[1]))
7077
7178 bet = ar .- ar[1 ] # trick: force 0 start, so this ignores orbit_start!
96103
97104
98105function parker_weight (sg:: SinoFan ; T:: Type{<:Real} = Float32):: Matrix{T}
99- wt = ones (T, dims (sg))
100106 if (sg. orbit ÷ 360 ) * 360 == sg. orbit
101- return wt
107+ return ones (T, 1 , 1 ) # no weighting needed
102108 end
103- return parker_weight_fan (
109+ return parker_weight_fan_short (
104110 sg. nb, sg. na, sg. orbit, sg. orbit_short,
105111 sg. ar, sg. gamma, sg. gamma_max; T
106112 )
107113end
108114
109115
110- function parker_weight (sg:: SinoMoj ; T:: Type{<:Real} = Float32):: Vector{T}
116+ function parker_weight (sg:: SinoMoj ; T:: Type{<:Real} = Float32)
111117 orbit = abs (sg. orbit)
112118 na = sg. na
113119 ((sg. orbit ÷ 180 ) * 180 == orbit) ||
114120 throw (" No Parker weighting for Mojette geometry with orbit=$orbit " )
115- wt = ones (T, na )
121+ wt = ones (T, 1 , 1 )
116122 return wt
117123end
124+
125+
126+ function parker_weight_fan_short (cg:: CtFan ; kwargs... )
127+ weight = parker_weight_fan_short (
128+ cg. ns, cg. na, cg. orbit, cg. orbit_short,
129+ cg. ar, cg. gamma, cg. gamma_max; kwargs... ,
130+ )
131+ weight .*= 360 / cg. orbit_short # trick due to scaling in cbct-back
132+ return weight
133+ end
134+
135+
136+ """
137+ parker_weight(cg::CtFan; T::Type{<:Real} = Float32, kwargs...)
138+ For 3D case, return `Array{T,3}` where size is
139+ - `(1,1,1)` typical fan case with 360° orbit
140+ - `(ns,1,na)` atypical fan case including short scan
141+ """
142+ function parker_weight (cg:: CtFan ; T:: Type{<:Real} = Float32, kwargs... )
143+ if (cg. orbit ÷ 360 ) * 360 == cg. orbit
144+ return ones (T, 1 , 1 , 1 ) # (1,1,1) for type stability
145+ end
146+ weight = parker_weight_fan_short (cg; kwargs... )
147+ weight = reshape (weight, dims (cg)[1 ], 1 , dims (cg)[3 ]) # (ns,1,na)
148+ return weight
149+ end
0 commit comments