NiftyPET / NIPET

High-throughput PET image reconstruction with high quantitative accuracy and precision
Apache License 2.0
29 stars 7 forks source link

dynamic_timings function does not include offset #55

Open davecash75 opened 4 months ago

davecash75 commented 4 months ago

Hi @pjmark- I was using the nipet.lm.get_time_offset to get the time offset due to injection delay, but when I then incorporate that value in nipet.lm.dynamic_timings per the documentation, the frame timings remain unchanged. When I had a bit of a dig into the code, it also seems that the resulting frame timings are dependent if you pass it a 1-D list versus the 2-D 'def' list approach. Since this function is pretty straightfoward and doesn't require any of the actual PET data to run, I've produced a toy example below. Also, with the 1-D list approach, would you expect there to be a first frame containing the data before the injection?

from niftypet import nipet

dframes = ['def', [4, 15],[8, 30], [9, 60], [2, 180], [8, 300]]
lframes = [ 15,15,15,15,
            30,30,30,30,30,30,30,30,
            60,60,60,60,60,60,60,60,60,
            180,180,
            300,300,300,300,300,300,300,300 ]

offset=0
# First assume no offset
frames = nipet.lm.dynamic_timings(lframes)
print(frames)
{'total': 3600, 'frames': array([ 15,  15,  15,  15,  30,  30,  30,  30,  30,  30,  30,  30,  60,
        60,  60,  60,  60,  60,  60,  60,  60, 180, 180, 300, 300, 300,
       300, 300, 300, 300, 300], dtype=uint16), 'timings': ['timings', [0, 15], [15, 30], [30, 45], [45, 60], [60, 90], [90, 120], [120, 150], [150, 180], [180, 210], [210, 240], [240, 270], [270, 300], [300, 360], [360, 420], [420, 480], [480, 540], [540, 600], [600, 660], [660, 720], [720, 780], [780, 840], [840, 1020], [1020, 1200], [1200, 1500], [1500, 1800], [1800, 2100], [2100, 2400], [2400, 2700], [2700, 3000], [3000, 3300], [3300, 3600]]}

# Get the same result when using the 2-D or 1-D list approach when no offset is provided
frames = nipet.lm.dynamic_timings(dframes)
print(frames)
{'total': 3600, 'frames': array([ 15,  15,  15,  15,  30,  30,  30,  30,  30,  30,  30,  30,  60,
        60,  60,  60,  60,  60,  60,  60,  60, 180, 180, 300, 300, 300,
       300, 300, 300, 300, 300], dtype=uint16), 'timings': ['timings', [0, 15], [15, 30], [30, 45], [45, 60], [60, 90], [90, 120], [120, 150], [150, 180], [180, 210], [210, 240], [240, 270], [270, 300], [300, 360], [360, 420], [420, 480], [480, 540], [540, 600], [600, 660], [660, 720], [720, 780], [780, 840], [840, 1020], [1020, 1200], [1200, 1500], [1500, 1800], [1800, 2100], [2100, 2400], [2400, 2700], [2700, 3000], [3000, 3300], [3300, 3600]]}

# Now let's pick an arbitrary offset value
offset=26
frames = nipet.lm.dynamic_timings(lframes,offset=offset)
# WIth a 1-D list, it produces a "zero-frame" the duration of offset, but this means there
# is a dimension mismatch between frames and timings
print(frames)
{'total': 3626, 'frames': array([ 15,  15,  15,  15,  30,  30,  30,  30,  30,  30,  30,  30,  60,
        60,  60,  60,  60,  60,  60,  60,  60, 180, 180, 300, 300, 300,
       300, 300, 300, 300, 300], dtype=uint16), 'timings': ['timings', [0, 26], [26, 41], [41, 56], [56, 71], [71, 86], [86, 116], [116, 146], [146, 176], [176, 206], [206, 236], [236, 266], [266, 296], [296, 326], [326, 386], [386, 446], [446, 506], [506, 566], [566, 626], [626, 686], [686, 746], [746, 806], [806, 866], [866, 1046], [1046, 1226], [1226, 1526], [1526, 1826], [1826, 2126], [2126, 2426], [2426, 2726], [2726, 3026], [3026, 3326], [3326, 3626]]}

# With dframes 2-D approach the values are the same as they are when offset is 0
frames = nipet.lm.dynamic_timings(dframes,offset=offset)
print(frames)
{'total': 3600, 'frames': array([ 15,  15,  15,  15,  30,  30,  30,  30,  30,  30,  30,  30,  60,
        60,  60,  60,  60,  60,  60,  60,  60, 180, 180, 300, 300, 300,
       300, 300, 300, 300, 300], dtype=uint16), 'timings': ['timings', [0, 15], [15, 30], [30, 45], [45, 60], [60, 90], [90, 120], [120, 150], [150, 180], [180, 210], [210, 240], [240, 270], [270, 300], [300, 360], [360, 420], [420, 480], [480, 540], [540, 600], [600, 660], [660, 720], [720, 780], [780, 840], [840, 1020], [1020, 1200], [1200, 1500], [1500, 1800], [1800, 2100], [2100, 2400], [2400, 2700], [2700, 3000], [3000, 3300], [3300, 3600]]}