-
Notifications
You must be signed in to change notification settings - Fork 89
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
Refactoring for origin shift #260
base: master
Are you sure you want to change the base?
Conversation
cc474c6
to
0365f96
Compare
Not sure about Similarly, Therefore I would not have these functions. Anyone who needs to do this will just have call 2 functions ( |
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 quite reasonable. Of course I have some suggestions...
Also a minor one: the comments here are obsolete?
->get_index_coordinates_for_gantry_coordinates | ||
(end_of_tor_projected_to_axis_without_offset, proj_data_info_sptr); | ||
|
||
const float first_lor_relative_to_tor |
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.
rename to z_index_start_of_tor
? Not sure why the relative_to_tor
? (but in the above I don't bother naming it...)
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 still not 100% sure about the add_adjacent_z
function, and find some of the variable naming in it a bit confusing. So in this section of code I have been careful to replicate functionality, but must admit I don't 100% understand what is happening, hence more bad variable names.
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.
Maybe
const float z_of_first_voxel_relative_to_start_of_tor
= z_of_first_voxel_in_index_space
- start_of_tor_projected_to_axis_without_offset.z();
= end_of_tconst·float·z_of_end_of_tor_relative_to_start_of_tor
or_projected_to_axis_without_offset.z()
- start_of_tor_projected_to_axis_without_offset.z();
?
|
||
add_adjacent_z(lor, z_of_first_voxel - left_edge_of_TOR, right_edge_of_TOR -left_edge_of_TOR); | ||
{ | ||
CartesianCoordinate3D<float> |
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 bit verbose.... just as well say
const float z_of_first_voxel_in_index_space = static_cast<float>(lor.bin()->coord1());
I'd rename that variable to z_index_of_first_voxel
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.
Maybe better is z_index_of_traced_lor
, with a comment explaining that this is constant because tantheta=0?
|
||
// In gantry space | ||
CartesianCoordinate3D<float> | ||
start_of_tor_projected_to_axis_without_offset |
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 somewhat confusing variable. It works because tantheta=0, and therefore x,y are irrelevant, but it's quite hard to understand what's going on here. (it was simpler before). I suggest to introduce a function
// The LOR is parametrised in terms of 'a'
CartesianCoordinate3D<float>
find_image_index_along_LOR(
const float s_in_mm, const float m_in_mm,
const float cphi, const float sphi,
const float tantheta,
const float a,
const DiscretisedDensity<3,float> & density_info,
const ProjDataInfo& proj_data_info);
Use this in ray_trace_one_lor
and use it here as
// some doc why a=0
const float a=0;
CartesianCoordinate3D<float>image_index_start_of_tor =
find_image_index_along_LOR(s_in_mm, m_in_mm - sampling_distance_of_adjacent_LORs_z/2...);
...
add_adjacent_z(lor, z_index_of_first_voxel - image_index_start_of_tor.z(),
image_index_end_of_tor.z() - image_index_start_of_tor.z());
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.
Good idea :)
I went a little further and split out a local function
CartesianCoordinate3D<float>
get_point_on_lor_in_index_coordinates
(const float s_in_mm, const float m_in_mm, const float a_in_mm,
const float cphi, const float sphi, const float tantheta,
const DiscretisedDensity<3, float>& density_info,
const ProjDataInfo& proj_data_info)
{
return density_info.get_index_coordinates_for_relative_coordinates
(proj_data_info.get_relative_coordinates_for_gantry_coordinates
(proj_data_info.get_point_on_lor_in_gantry_coordinates
(s_in_mm, m_in_mm, a_in_mm, cphi, sphi, tantheta)));
}
and method
CartesianCoordinate3D<float>
ProjDataInfo::get_point_on_lor_in_gantry_coordinates
(const float s_in_mm, const float m_in_mm, const float a_in_mm,
const float cphi, const float sphi, const float tantheta) const
{
return CartesianCoordinate3D<float>(m_in_mm - a_in_mm*tantheta, // z
s_in_mm*sphi - a_in_mm*cphi, // y
s_in_mm*cphi + a_in_mm*sphi); // x
}
const float offset_in_z, | ||
const float fovrad_in_mm, | ||
const CartesianCoordinate3D<float>& voxel_size, | ||
const bool restrict_to_cylindrical_FOV, | ||
const int num_LORs) | ||
const int num_LORs, | ||
const shared_ptr< DiscretisedDensity<3,float> >& |
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.
no reason to drag shared_ptr
along. just use const DiscretisedDensity<3,float>&
(shorter and less dependent on choices made elsewhere). Alternatively, make this a private function, in which case you dont need to pass them along.
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.
Sounds good
I agree, but had some difficulty drawing a clear line in the separation here. It is quite obviously ugly as it is now, requiring a reference to a ProjDataInfo in the function, so I am happy for suggestions. The problem is that in the projection space, the FoR is the centre of the gantry. Whereas in Discretised Density, it is from the first ring. So querying ProjDataInfo for the centre in its own coordinates would be (0, 0, 0). So somewhere, there should be a function that essentially adds the vector from the centre of first ring to the center of the gantry. That's what But this would still have ProjDataInfo knowing a little bit about relative coordinates. To avoid ambiguity, I think there should be a function somewhere that converts sinogram-based coordinates (from get_m, etc, which are from center) to relative coordinates. |
Its a bit confusing because I am using the terminology gantry_coordinates to mean gantry-based but also with FoR at centre. You could define bed_coordinates to have FoR either at centre or at end of first ring. |
Yes, and I have modified the explanation following slightly |
Looking at the failed test, it seems these changes break the symmetries test. But I'm not too sure why this would be, nothing that I changed in PRMT seems to be symmetry-specific. The errors look like:
So looks like the z voxel is different if symmetries are/aren't used. |
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 hopefully helpful comments.
I'm a bit reluctant to merge in all the ORIGINTODO mods. we should have them, but probably not on master.... Easy to remove that commit?
@@ -41,6 +41,7 @@ | |||
#include "stir/CartesianCoordinate3D.h" | |||
#include "stir/Array.h" | |||
#include "stir/IO/ExamData.h" | |||
#include "stir/ProjDataInfo.h" |
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.
shouldn't be needed if it wasn't before (will need to be in cxx, but probably already there)
@@ -344,6 +347,7 @@ set_up( | |||
// test if our 2D code does not have problems | |||
{ | |||
// currently 2D code relies on the LOR falling in the middle of a voxel (in z-direction) | |||
// If reactivated, update to use proper index -> physical space conversion |
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.
not sure what is meant by if reactivated
(min(max_index.y(), -min_index.y())+.45F)*voxel_size.y()); | ||
CartesianCoordinate3D<float> max_pos = | ||
density_info_sptr | ||
->get_relative_coordinates_for_indices(max_index + 0.45F); |
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 think best to use physical
. At some point, we will allow x/y-offset shifts. The "relative" coordinates won't see this, and therefore we would use the wrong FOV
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, I'd like to phase out all relative coordinates, either removing the methods or changing them to private.
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.
let's just make them private (or protected) in a first (2nd?) stage
// within the TOR, leveraging our traced LOR | ||
|
||
// since tantheta==0, z is constant | ||
const float z_of_traced_lor |
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.
best to call this variable (and the next ones) z_index...
…atrixByBinUsingRayTracing
…n ProjMatrixByBinUsingRayTracing
Now passes until non-standard range of planes.
2153632
to
120419c
Compare
@KrisThielemans I've got something like this: CartesianCoordinate3D<float>
ProjDataInfo::
get_physical_coordinates_for_gantry_coordinates
(const CartesianCoordinate3D<float>& coords, const shared_ptr<DiscretisedDensity<3,float> >& image_sptr) const
{
// TODO: bed postion
return coords + get_gantry_origin_in_physical_coordinates(image_sptr);
} and CartesianCoordinate3D<float>
ProjDataInfo::
get_gantry_origin_in_physical_coordinates(const shared_ptr<DiscretisedDensity<3,float> >& image_sptr) const
{
// TODO - STIR currently enforces that an image is centred in the z-plane.
// In future, this would make more sense to be implemented as:
// float middle_of_first_ring_to_middle_of_last
// = (scanner_ptr->get_num_rings() - 1) * scanner_ptr->get_ring_spacing();
// return CartesianCoordinate3D<float>(middle_of_first_ring_to_middle_of_last / 2.F, 0, 0);
// shift by vector to centre of image in z (assume this corresponds to centre of gantry)
CartesianCoordinate3D<int> min_index;
CartesianCoordinate3D<int> max_index;
image_sptr->get_regular_range(min_index, max_index);
CartesianCoordinate3D<float> middle_of_image = image_sptr->get_physical_coordinates_for_indices(
(min_index + max_index) / 2.);
return CartesianCoordinate3D<float>(middle_of_image.z(), 0, 0);
} |
it's ugly indeed, but I also can't see a way around it for now.
I'm not sure why that creates problems. as long as we pre-declare DD in PDI.h and PDI in DD.h, then the implementations can sit in the .cxx. Everything should compile and link ok. Maybe you can send the compilation error? By the way, I'd like to avoid using |
Okay, so shared pointer should only be used if the object stores a reference as a member? ProjDataInfo.cxx.o builds okay, but later it gets to DiscretisedDensity.cxx.o, and I get an error then:
So it seems to be some weird circular thing maybe? |
I |
in .h, you should use template <blabla> class DD; In the .cxx, you include DD.h |
that's confusingly phrased :-) but yes, I feel more and more it should only be used if we really are going to share ownership (there's too many places in STIR that do...). It makes it semantically clear, it allows calling it with actual objects (e.g. of type |
should add this to the developer's guide really... |
This PR Shouldn't actually change any functionality, just using the correct routines where they should be.
NB: I haven't had time to test changes to scatter.