xcist / main

simulation and reconstruction package
BSD 3-Clause "New" or "Revised" License
47 stars 24 forks source link

Beam hardening not observed in results #5

Closed ltldlzltl closed 2 years ago

ltldlzltl commented 2 years ago

Hi guys,

In my recent simulations, I found that beam hardening is not significant in the reconstruction results. To verify this, I built a water cylinder phantom and simulated the projection data with XCIST under a 120 kV spectrum. The reconstruction is done with ASTRA toolbox. Here is what I got. 1637206428(1) I also plotted the center row. 1637206494(1) Results show that there is no beam bardening artifact at all. My scan protocal

protocol.scanTypes = [1, 1, 1]              # flags for airscan, offset scan, phantom scan

# Table and gantry
protocol.scanTrajectory = "Gantry_Helical"  # name of the function that defines the scanning trajectory and model
protocol.viewsPerRotation = 600             # total numbers of view per rotation
protocol.viewCount = 600                    # total number of views in scan
protocol.startViewId = 0                    # index of the first view in the scan
protocol.stopViewId = protocol.startViewId+protocol.viewCount-1 # index of the last view in the scan
protocol.airViewCount = 50                  # number of views averaged for air scan
protocol.offsetViewCount = 50               # number of views averaged for offset scan
protocol.rotationTime = 40.0                # gantry rotation period (in seconds)
protocol.rotationDirection = 1              # gantry rotation direction (1=CW, -1 CCW, seen from table foot-end)
protocol.startAngle = 0                     # relative to vertical y-axis (n degrees)
protocol.tableSpeed = 0                     # speed of table translation along positive z-axis (in mm/sec)
protocol.startZ = 0                         # start z-position of table
protocol.tiltAngle = 0                      # gantry tilt angle towards negative z-axis (in degrees)
protocol.wobbleDistance = 0.0               # focalspot wobble distance
protocol.focalspotOffset = [0, 0, 0]        # focalspot position offset

# X-ray tube technique and filtration
protocol.mA = 8                             # tube current (in mA)
protocol.spectrumCallback = "Spectrum"      # name of function that reads and models the X-ray spectrum
protocol.spectrumFilename = "tungsten_tar7_120_unfilt.dat" # name of the spectrum file
protocol.spectrumScaling = 1                # scaling factor such that spectrum is in photons / mA / s / mm^2 at 1000 mm
protocol.bowtie = []                        # name of the bowtie file (or [])
protocol.filterCallback = "Xray_Filter"     # name of function to compute additional filtration
protocol.flatFilter = []            # additional filtration - materials and thicknesses (in mm)
protocol.dutyRatio = 1.0                    # tube ON time fraction (for pulsed tubes)

Physics configurations

# Geometric and energy sampling
physics.energyCount = 110
physics.monochromatic = -1
physics.colSampleCount = 1
physics.rowSampleCount = 1
physics.srcXSampleCount = 1
physics.srcYSampleCount = 1
physics.viewSampleCount = 1

# Flags to determine what has to be recalculated each view
physics.recalcDet = 0
physics.recalcSrc = 0
physics.recalcRayAngle = 0
physics.recalcSpec = 0
physics.recalcFilt = 0
physics.recalcFlux = 0
physics.recalcPht = 0
physics.recalcDet = 0

# Noise on/off settings
physics.enableQuantumNoise = 0
physics.enableElectronicNoise = 0

# Internal physics models
physics.rayAngleCallback = "Detector_RayAngles_2D"
physics.fluxCallback = "Detection_Flux"
physics.scatterCallback = ""
physics.prefilterCallback = "Detection_prefilter"
physics.crosstalkCallback = ""
physics.lagCallback = ""
physics.opticalCrosstalkCallback = ""
physics.DASCallback = "Detection_DAS"

# I/O preferences
physics.outputCallback = "WriteRawView"

Scanner protocol

# Scanner geometry
scanner.detectorCallback = "Detector_ThirdgenCurved" # name of function that defines the detector shape and model
scanner.sid = 617.0                         # source-to-iso distance (in mm)
scanner.sdd = 1140.0                        # source-to-detector distance (in mm)
scanner.detectorColsPerMod = 1024           # number of detector columns per module
scanner.detectorRowsPerMod = 1024           # number of detector rows per module
scanner.detectorColOffset = 0.0             # detector column offset relative to centered position (in detector columns)
scanner.detectorRowOffset = 0.0             # detector row offset relative to centered position (in detector rows)
scanner.detectorColSize = 0.45              # detector column pitch or size (in mm)
scanner.detectorRowSize = 0.45              # detector row pitch or size (in mm)
scanner.detectorColCount = scanner.detectorColsPerMod     # total number of detector columns
scanner.detectorRowCount = scanner.detectorRowsPerMod     # total number of detector rows
scanner.detectorPrefilter = []              # detector filter

# X-ray tube
scanner.focalspotCallback = "Source_Uniform" # name of function that defines the focal spot shape and model
scanner.targetAngle = 7.0                   # target angle relative to scanner XY-plane (in degrees)
scanner.focalspotWidth = 1.0
scanner.focalspotLength = 1.0

# Detector
scanner.detectorMaterial = "CsI"            # detector sensor material
scanner.detectorDepth = 3.0                 # detector sensor depth (in mm)
scanner.detectionCallback = "Detection_EI"  # name of function that defines the detection process (conversion from X-rays to detector signal)
scanner.capacitor = 0.5                     # capacity of the readout capacitor (in pF)
scanner.readoutVolt = 5                     # voltage for readout ADC (in V)
scanner.maxReadout = 65535                  # maximum readout
scanner.detectionGain = 10.0                # factor to convert energy to electrons (electrons / keV)
scanner.detectorColFillFraction = 1.0       # active fraction of each detector cell in the column direction
scanner.detectorRowFillFraction = 1.0       # active fraction of each detector cell in the row direction
scanner.eNoise = 10.0                       # standard deviation of Gaussian electronic noise (in electrons)

Any idea why there is no beam hardening artifact?

MingyeWu commented 2 years ago

Hi Tianling, I'd like to double check the recon first. Could you run the simulation with a phantom that has some structures, so that we can make sure the recon works correctly?

ltldlzltl commented 2 years ago

Hi Tianling, I'd like to double check the recon first. Could you run the simulation with a phantom that has some structures, so that we can make sure the recon works correctly? lung Hi, here is a recon example on male lung phantom. I turned off noise simulation in this example.

MingyeWu commented 2 years ago

Hi Tianling, Do you still have the issue that it doesn't show BH artifacts? If yes, maybe try: 1) update the code to the latest version; 2) use the sample main/examples/Sim_Sample_Analyic.py, AND remove the bowtie (set cfg.protocol.bowtie = ""), AND set ct.physics.callback_post_log = "" (Disable BHC).

MingyeWu commented 2 years ago

One more suggestion is that you may try the analytical water phantom, we have demonstrated BH artifacts in a study (will be published soon), in the latest code, please refer xcist\main\examples\Sim_Sample_Analyic.py

If you have more questions, please let us know.