-
Notifications
You must be signed in to change notification settings - Fork 119
BUG: Fix minor errors in mayo geometry definitions #1383
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
Conversation
odl/contrib/datasets/ct/mayo.py
Outdated
|
|
||
| # TODO: WE CURRENTLY IGNORE THE OFFSETS DUE TO FLYING FOCAL SPOT | ||
| source_offsets = np.array([offset_x, offset_y, offset_z]).T | ||
| # Make a parallel beam geometry with flat detector |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong comment
odl/contrib/datasets/ct/mayo.py
Outdated
| src_radius = src_radius + np.mean(offset_radial) | ||
| angles = angles - np.mean(offset_angular) | ||
|
|
||
| # print(np.mean(offset_angular)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove print
|
I guess this isn't quite ready for review yet |
|
Its reviewable, just some minor stuff to fix. |
219f485 to
bd7cb07
Compare
kohr-h
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too familiar with the conventions, so I can't say anything about correctness. But still one thing I should understand but don't.
odl/contrib/datasets/ct/mayo.py
Outdated
|
|
||
| # TODO: WE CURRENTLY IGNORE THE OFFSETS DUE TO FLYING FOCAL SPOT | ||
| source_offsets = np.array([offset_x, offset_y, offset_z]).T | ||
| if 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is for development only?
If not, I'm not in favor of "parking" backup code like this. Better make an issue and post the old code there for reference. It's also in the git history anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove it.
odl/contrib/datasets/ct/mayo.py
Outdated
| source_offsets = np.array([offset_x, offset_y, offset_z]).T | ||
| if 1: | ||
| # Apply only mean of offsets | ||
| src_radius = src_radius + np.mean(offset_radial) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get this. How could this ever work before if it's a vector? In the old version, src_rad_offset must have been a vector, and with it all 3 offsets as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically the offsets are weird, so I decided to just go for their means. Before we did not do anything about it (src_rad_offset was unused) which gave some slight errors, since apparently the "offsets" are not zero-centered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. What I was puzzled about was that in the old version, src_radius became a vector (after adding offset_radial), then it was used to compute offset_[xyz], each of which also was a vector then, and the final source_offsets stacked them to a matrix. I don't see how that made sense.
Anyhow, for some other PR.
0cda683 to
5098fad
Compare
|
With some further small fixes, it now actually looks like this does the right thing, and there are no magic numbers! A note to future readers (e.g myself in a year): The tags "SpiralPitchFactor" and "TableFeedPerRotation" are slightly bugged and not to be trusted. |
|
Could use a final review on this |
aringh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, but honestly I am not too familiar with the dicom format and with the mayo-data.
| data_array /= 1024.0 | ||
| # Convert from storage type to densities | ||
| # TODO: Optimize these computations | ||
| hu_values = (dataset.RescaleSlope * data_array + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I will reveal my lack of knowledge in this field: what is the difference between this hu_values and the hu_factor on line 57?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hu_values is an array (basically the image) while hu_factor is an integer specifying how to rescale values.
Basically DICOM stores everything as positive integers, and then has information on how to convert this into usable stuff by rescaling. That's what I do here. I also follow up by moving from HU values to densities (of water) since the values are much easier to work with later on.
kohr-h
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comments, but largely good to go.
As before, I assume the code is correct. It does make sense on a high level.
odl/contrib/datasets/ct/mayo.py
Outdated
| src_radius / (src_radius + det_radius)) | ||
|
|
||
| # Convert offset to odl defintions | ||
| offset_along_axis = (offset_along_axis + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not +=?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to keep this as a "unified" assignment. I'd actually prefer to replace the "old" offset_along_axis to something like "mean_offset_along_axis_for_ffz". It's also more honest.
odl/contrib/datasets/ct/mayo.py
Outdated
| if len(datasets) > 1: | ||
| slice_distance = np.abs( | ||
| np.array(datasets[1].DataCollectionCenterPatient)[2] - | ||
| np.array(datasets[0].DataCollectionCenterPatient)[2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
np.array shouldn't be necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DataCollectionCenterPatient[2] is a string.
Although I guess float would make more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, definitely. I thought it was a list.
| min_pt[2] -= 0.5 * slice_distance | ||
| max_pt[2] = -np.array(datasets[-1].DataCollectionCenterPatient)[2] | ||
| max_pt[2] += 0.5 * pixel_thickness | ||
| max_pt[2] += 0.5 * slice_distance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the overall logic of computing the min/max in the z axis? Does it go from -(patient z in dataset 0) to 0, adjusted by half a slice distance in each direction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, maybe a comment could make that more obvious, I had to think about it for a second. Maybe also the review markup was a bit to blame.
| # Apply only mean of offsets | ||
| src_radius = src_radius + np.mean(offset_radial) | ||
| offset_along_axis = np.mean(offset_axial) * ( | ||
| src_radius / (src_radius + det_radius)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment on why the multiplication with the magnification factor? (Which BTW would be a good name for a temp variable, to clarify things a bit.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to write this down, but overall this really needs a whiteboard
odl/contrib/datasets/ct/mayo.py
Outdated
| offset_y = (np.sin(angles_offset) * (-src_rad_offset) - | ||
| np.sin(angles) * (-src_radius)) | ||
| offset_z = offset_axial | ||
| # Correct the angular sampling according to corrections |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't really say anything
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree
| angles[0] / (2 * np.pi) * pitch) | ||
| # For unknown reasons, mayo does not include the tag | ||
| # "TableFeedPerRotation", which is what we want. | ||
| # Instead we manually compute the pitch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great comment!
odl/contrib/datasets/ct/mayo.py
Outdated
|
|
||
| # TODO: WE CURRENTLY IGNORE THE OFFSETS DUE TO FLYING FOCAL SPOT | ||
| source_offsets = np.array([offset_x, offset_y, offset_z]).T | ||
| # TODO: Implement proper handling of flying focal spot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about you write # TODO(adler-j)? Then people looking at this know whom to ask without doing a git blame.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do!
|
Fixed comments, merge after CI. |
It seems we had some minor (but notable in some cases) errors with the geometry descriptions.