8000 Support for plotting helical trajectory with curved detector? · Issue #150 · LLNL/LEAP · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Support for plotting helical trajectory with curved detector? #150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ProjX0 opened this issue Feb 24, 2025 · 5 comments
Open

Support for plotting helical trajectory with curved detector? #150

ProjX0 opened this issue Feb 24, 2025 · 5 comments

Comments

@ProjX0
Copy link
ProjX0 commented Feb 24, 2025

Can the d09_curved_polygon_detector_array.py script plot a helical trajectory along with the curved detector using matplotlib (plt)?

@ProjX0
Copy link
Author
ProjX0 commented Feb 24, 2025

Below is the modified d09_curved_polygon_detector_array.py where I have changed the geometry variables. I would like to visualize the geometry by plotting it along with a helical trajectory in the CT geometry of the "true" system.

import sys
import os
import time
import numpy as np
import matplotlib.pyplot as plt
from leapctype import *

# First we define the geometry
numCols_per_module = 80
numSticks = 48
numCols = numSticks*numCols_per_module
numRows = 128
numAngles = 720
pixelSize = 0.15 # mm

# Set source-to-object and source-to-detector distances
sod = 330.0
sdd = sod + 280.0

leapct_regular = tomographicModels()

# Define the angular rotation samples
phis = leapct_regular.setAngleArray(numAngles, 360.0)

# Set the regular geometry as a curved cone-beam system
leapct_regular.set_conebeam(numAngles, numRows, numCols, pixelSize, pixelSize, 0.5*(numRows-1), 0.5*(numCols-1), phis, sod, sdd)
leapct_regular.set_curvedDetector()
leapct_regular.set_normalizedHelicalPitch(0.5)
leapct_regular.set_volume(numCols, numCols, numRows, pixelSize*sod/sdd, pixelSize*sod/sdd)
# leapct_regular.set_volume(100, 100, 100, 0.17, 0.17)

g = leapct_regular.allocate_projections()


# Make another tomographicModels object to track the true geometry
leapct_true = tomographicModels()

# Define the angular spacing between detector modules
#angularSpacing = np.arctan(pixelSize*numCols_per_module / sdd)
angularSpacing = np.arctan((pixelSize*numCols_per_module + 1.0) / sdd)

# Define the angles of each module
alphas = (np.array(range(numSticks))-(numSticks-1)/2.0)*angularSpacing

# Now we define the CT geometry of the "true" system
leapct_true.set_volume(numCols, numCols, numRows, pixelSize*sod/sdd, pixelSize*sod/sdd)
f = leapct_true.allocateVolume() # shape is numZ, numY, numX
leapct_true.set_FORBILD(f,True)

for n in range(numAngles):
    phi = phis[n]*np.pi/180.0 - np.pi/2.0
    sourcePositions = np.zeros((numSticks,3),dtype=np.float32)
    sourcePositions[:,0] = sod*np.cos(phi)
    sourcePositions[:,1] = sod*np.sin(phi)
    moduleCenters = np.zeros((numSticks,3),dtype=np.float32)
    colVectors = np.zeros((numSticks,3), dtype=np.float32)
    rowVectors = np.zeros((numSticks,3), dtype=np.float32)
    rowVectors[:,2] = 1.0
    for m in range(numSticks):
        colVectors[m,0] = -np.sin(phi-alphas[m])
        colVectors[m,1] = np.cos(phi-alphas[m])
        moduleCenters[m,0] = -sdd*np.cos(phi-alphas[m])+sourcePositions[m,0]
        moduleCenters[m,1] = -sdd*np.sin(phi-alphas[m])+sourcePositions[m,1]
    
    leapct_true.set_modularbeam(numSticks, numRows, numCols_per_module, pixelSize, pixelSize, sourcePositions, moduleCenters, rowVectors, colVectors)
    leapct_true.set_normalizedHelicalPitch(0.5)
    g_sim = leapct_true.allocateProjections() # shape is numAngles, numRows, numCols
    

    leapct_true.sketch_system()
    
    # "Simulate" the data
    leapct_true.project(g_sim,f)

    # Concatenate the projections onto each modular into one projection
    for m in range(numSticks):
        g[n,:,m*numCols_per_module:(m+1)*numCols_per_module] = g_sim[m,:,:]


# To enable the rebinning, we must specify the angle (in degrees) of each detector pixel along a single row
fanAngles = np.array(range(numCols),dtype=np.float32)
fanAngles_per_module = (np.array(range(numCols_per_module))-(numCols_per_module-1)/2.0)*np.arctan(pixelSize/sdd)
for m in range(numSticks):
    fanAngles[m*numCols_per_module:(m+1)*numCols_per_module] = alphas[m]+fanAngles_per_module
fanAngles *= 180.0/np.pi

# Now perform the rebinning.  The "order" argument specifies the order of the interpolating polynomial.
startTime = time.time()
leapct_regular.rebin_curved(g, fanAngles, order=6)
leapct_regular.sketch_system()
print('Rebinning Elapsed Time: ' + str(time.time()-startTime) + ' seconds')

# Finally, perform FBP reconstruction and display the result
f = leapct_regular.FBP(g)
f[f<0.0] = 0.0
plt.imshow(np.squeeze(f[f.shape[0]//2,:,:]), cmap=plt.get_cmap('gray'))
plt.show()

@kylechampley
Copy link
Collaborator

Yes, I agree that the sketch_system function needs improvements. I am interested in improving it, but not sure when I will have time to get to this.

@ProjX0
Copy link
Author
ProjX0 commented Mar 4, 2025

I understand. I'll be looking forward to your improvements whenever you have the time to work on them!
Thank you

@ProjX0
Copy link
Author
ProjX0 commented Mar 4, 2025

I modified the internal source code for sketch_system(). So, it's not perfect like the picture below, but I made a temporary representation of the geometry with helical trajectory and curved detector.

Image

@kylechampley
Copy link
Collaborator

Looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
0