jerichooconnell/fastcat

Question on use of different geometries

Closed this issue · 17 comments

Hello!

I am wondering whether I can use FastCAT to generate CTs for a much smaller volume: let's say on a scale of a mouse. I saw in the paper that you use the Catphan phantom and the scatter data was only generated for that. Obviously, that can't be used but I assume that scatter-free CBCTs can still be generated.

Yes in the return_projections method specify scat_on=False to give no scatter. And the geometry can be changed in the phantom.geomet object. If you print phantom.geomet it will tell you what your current geometry looks like.

You would have to make your own mouse phantom with integer values corresponding to materials.

Hi. Sorry for the late response. I was away at a conference.
I'll give it a try. Thanks!

Hi. If the material that I want to assign is not in the database, I am assuming that I have to add it. I saw that you used the physdata package to get the attenuation coefficients but if the material does not exist in the NIST database, can this still be used?

Sorry. Another question.
I read the paper and for the CsI detector, it was written that you simulated a 450 um thick scintillator. However, when I look at the code, you have different versions and I am assuming that the numbers correspond to the thickness of the scintillator. Is that correct?

Nevermind my previous questions. I figured it out.
Just a follow up on the scatter kernels. I don't exactly understand how you generated them. Can you explain a bit more on what do the scatter curves contain? Thanks!

Hi. This is the one I wanted some clarification about. I already did some MC simulations to calculate the scatter similar to the paper but I am not quite sure what the scatter kernels should contain. Should I provide a percentage or scatter-to-primary ratio? I looked at the scatter files that you had but they looked like counts to me but that would mean that I would also need the primary so that the scaling would be correct.

Oh lord is my code not user friendly! I usually don't modify the primary signal. There is slightly different r squared distortion across the flat panel but I don't think it effects much. I usually just calculate a scatter file, I did one recently for a different set of energies which is in the time features so watch out

Looks like 2e8 initial photons
Catphan_scatter_in_phasespace.txt

And now that I think about it I should probably be modifying the primary due to the different geometry

That's exactly what I was gonna say and I was trying to find where I could change the primary file but I am not sure where and if I can do that.

Another question about the scatter. In the paper, it is written that you averaged the scattered particles in the z-direction. How exactly did you do that? Because for me, what would be intuitive to do is just integrate them in that direction. Or am I misunderstanding something here?

Oh lord it looks like I hardcoded the primary as 660 counts with an analytical approximation of the curvature in simulate.py so this bug probably means that I should modify the code to take both a scatter and a primary file, which I did do at one point.

These things like hardcoding counts and averaging over the z direction were ways of reducing the noise in the signal as I wanted fastcat to have the capability of generating completely noise free simulations that included scatter. Since this is sometimes fun to look at

You could load a npy file that has your primary counts for the same beam as your scatter into the variable flood_photon_counts in simulate.py

Since it is only counts it should be the same for all energies

I see. So the flood_photon_counts is then just the primary distribution after the water phantom. Now, I am a little bit confused because in the following lines

fastcat/fastcat/simulate.py

Lines 677 to 706 in 03d32e6

# --------------------------------------------------
# ---------- Attenuation to Intensity ---------------
# --------------------------------------------------
# We use the flood field profile to get intensity from
# the attenuation. We need intensity to calculate the
# noise and convolve with PSF.
# Intensity temp at this point is weighted by fluence
# energy and the detector response which is what the
# detector sees.
# if self.filter_on:
if scat_on:
int_temp = (
(
np.exp(-0.97 * attenuation / 10)
* (flood_photon_counts[jj])
)
+ mc_scatter[:, jj]
) * w_fluence_times_p_detected[
jj
]
else:
int_temp = (
(
np.exp(-0.97 * attenuation / 10)
* (flood_photon_counts[jj])
)
) * w_fluence_times_p_detected[
jj
] # 0.97 JO

you calculate the intensity after an attenuating material but then shouldn't you use the un-attenuated beam instead of flood_photon_counts? The modification of the primary due to the attenuating material in its path would already come from the np.exp(-0.97*attenuation/10) part.

Nevermind my previous post. I figured it out.