Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
ashgillman committed Jul 7, 2020
1 parent 49067db commit 02fda25
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 126 deletions.
21 changes: 15 additions & 6 deletions src/buildblock/ProjDataInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -655,21 +655,30 @@ operator>=(const ProjDataInfo& proj_data_info) const
}

CartesianCoordinate3D<float>
ProjDataInfo::
get_bed_position() const
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>
(bed_position_horizontal, bed_position_vertical, 0);
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
}

CartesianCoordinate3D<float>
ProjDataInfo::
get_centre_of_gantry_vector_in_relative_coordinates() const
get_vector_centre_of_first_ring_to_centre_of_gantry() const
{
double middle_of_first_ring_to_middle_of_last
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);
}

CartesianCoordinate3D<float>
ProjDataInfo::get_bed_position() const
{
return CartesianCoordinate3D<float>
(bed_position_horizontal, bed_position_vertical, 0);
}

END_NAMESPACE_STIR

5 changes: 1 addition & 4 deletions src/buildblock/ProjDataInfoCylindrical.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,14 @@ initialise_ring_diff_arrays() const
VectorWithOffset<float>(get_min_segment_num(),get_max_segment_num());

/* m_offsets are found by requiring
get_m(..., min_axial_pos_num,...) == - get_m(..., max_axial_pos_num,...),
and then shift from the centre to first ring and account for bed position
get_m(..., min_axial_pos_num,...) == - get_m(..., max_axial_pos_num,...)
*/
for (int segment_num=get_min_segment_num(); segment_num<=get_max_segment_num(); ++segment_num)
{
m_offset[segment_num] =
((get_max_axial_pos_num(segment_num) + get_min_axial_pos_num(segment_num))
*get_axial_sampling(segment_num)
)/2;
// ORIGINTODO: ^
}
}
// initialise ax_pos_num_offset
Expand Down Expand Up @@ -271,7 +269,6 @@ initialise_ring_diff_arrays() const
const float ring1_plus_ring2_float =
2*ax_pos_num/get_num_axial_poss_per_ring_inc(s_num)
-2*m_offset[s_num]/ring_spacing + (get_scanner_ptr()->get_num_rings()-1);
// ORIGINTODO: ^
const int ring1_plus_ring2 =
round(ring1_plus_ring2_float);
// check that it was integer
Expand Down
3 changes: 1 addition & 2 deletions src/buildblock/ProjDataInfoCylindricalNoArcCorr.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ find_scanner_coordinates_given_cartesian_coordinates(int& det1, int& det2, int&
det2 = modulo(round(cyl_coords.p2().psi()/(2.*_PI/num_detectors)), num_detectors);
ring1 = round(cyl_coords.p1().z()/ring_spacing);
ring2 = round(cyl_coords.p2().z()/ring_spacing);
// ORIGINTODO: ^

#endif

Expand Down Expand Up @@ -490,7 +489,7 @@ find_cartesian_coordinates_given_scanner_coordinates (CartesianCoordinate3D<floa
LORInCylinderCoordinates<float> cyl_coords(get_scanner_ptr()->get_effective_ring_radius());
cyl_coords.p1().psi() = static_cast<float>((2.*_PI/num_detectors_per_ring)*(det1));
cyl_coords.p2().psi() = static_cast<float>((2.*_PI/num_detectors_per_ring)*(det2));
cyl_coords.p1().z() = Ring_A*get_scanner_ptr()->get_ring_spacing();
cyl_coords.p1().z() = Ring_A*get_scanner_ptr()->get_ring_spacing();
cyl_coords.p2().z() = Ring_B*get_scanner_ptr()->get_ring_spacing();
// ORIGINTODO: ^
LORAs2Points<float> lor(cyl_coords);
Expand Down
10 changes: 0 additions & 10 deletions src/include/stir/DiscretisedDensity.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,6 @@ template<int num_dimensions, typename elemT>
inline BasicCoordinate<num_dimensions,int>
get_indices_closest_to_LPS_coordinates(const CartesianCoordinate3D<float>& coords) const;

inline CartesianCoordinate3D<float>
get_relative_coordinates_for_gantry_coordinates
(const CartesianCoordinate3D<float>& coords,
const shared_ptr<const ProjDataInfo> proj_data_info_sptr) const;

inline BasicCoordinate<num_dimensions, float>
get_index_coordinates_for_gantry_coordinates
(const CartesianCoordinate3D<float>& coords,
const shared_ptr<const ProjDataInfo> proj_data_info_sptr) const;

//@}

//! Allocate a new DiscretisedDensity object with same characteristics as the current one.
Expand Down
25 changes: 0 additions & 25 deletions src/include/stir/DiscretisedDensity.inl
Original file line number Diff line number Diff line change
Expand Up @@ -304,29 +304,4 @@ get_indices_closest_to_LPS_coordinates(const CartesianCoordinate3D<float>& coord
return round(this->get_index_coordinates_for_LPS_coordinates(coords));
}

template<int num_dimensions, typename elemT>
CartesianCoordinate3D<float>
DiscretisedDensity<num_dimensions, elemT>::
get_relative_coordinates_for_gantry_coordinates
(const CartesianCoordinate3D<float>& coords,
const shared_ptr<const ProjDataInfo> proj_data_info_ptr) const
{
// gantry coordinates are like relative coordinates, but the (0, 0, 0)
// point is at the center of the gantry
return coords
+ proj_data_info_ptr->get_centre_of_gantry_vector_in_relative_coordinates();
}

template<int num_dimensions, typename elemT>
BasicCoordinate<num_dimensions,float>
DiscretisedDensity<num_dimensions, elemT>::
get_index_coordinates_for_gantry_coordinates
(const CartesianCoordinate3D<float>& coords,
const shared_ptr<const ProjDataInfo> proj_data_info_ptr) const
{
return this->get_index_coordinates_for_relative_coordinates
(this->get_relative_coordinates_for_gantry_coordinates
(coords, proj_data_info_ptr));
}

END_NAMESPACE_STIR
22 changes: 18 additions & 4 deletions src/include/stir/ProjDataInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,16 @@ class ProjDataInfo
const Bin&) const = 0;
//@}

//! Get a point in gantry space along an LOR
/*!
The point is parameterised by s, a, m, cos(phi), sin(phi) and tan(theta).
Gantry space is defined w.r.t. the center of the gantry.
*/
virtual CartesianCoordinate3D<float>
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;

//! \name Functions that return info on the sampling in the different coordinates
//@{
//! Get sampling distance in the \c t coordinate
Expand Down Expand Up @@ -379,9 +389,10 @@ class ProjDataInfo
//! Vector represention bed position in 3D
CartesianCoordinate3D<float> get_bed_position() const;

//! Vector from image frame of reference (centre of first ring) to gantry centre
CartesianCoordinate3D<float>
get_centre_of_gantry_vector_in_relative_coordinates() const;
// Convert coordinates from a sinogram-based
inline CartesianCoordinate3D<float>
get_relative_coordinates_for_gantry_coordinates
(const CartesianCoordinate3D<float>& coords) const;

protected:
virtual bool blindly_equals(const root_type * const) const = 0;
Expand All @@ -396,7 +407,10 @@ class ProjDataInfo
VectorWithOffset<int> max_axial_pos_per_seg;
float bed_position_horizontal;
float bed_position_vertical;


//! Vector from image frame of reference (centre of first ring) to gantry centre
CartesianCoordinate3D<float>
get_vector_centre_of_first_ring_to_centre_of_gantry() const;
};

END_NAMESPACE_STIR
Expand Down
9 changes: 9 additions & 0 deletions src/include/stir/ProjDataInfo.inl
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ ProjDataInfo::get_scanner_sptr() const
return scanner_ptr;
}

CartesianCoordinate3D<float>
ProjDataInfo::
get_relative_coordinates_for_gantry_coordinates
(const CartesianCoordinate3D<float>& coords) const
{
// TODO: bed postion
return coords + get_vector_centre_of_first_ring_to_centre_of_gantry();
}


int
ProjDataInfo::get_num_sinograms() const
Expand Down
134 changes: 59 additions & 75 deletions src/recon_buildblock/ProjMatrixByBinUsingRayTracing.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,19 @@ static inline int sign(const T& t)
return t<0 ? -1 : 1;
}

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)));
}

// just do 1 LOR, returns true if lor is not empty
static void
ray_trace_one_lor(ProjMatrixElemsForOneBin& lor,
Expand All @@ -401,9 +414,8 @@ ray_trace_one_lor(ProjMatrixElemsForOneBin& lor,
const CartesianCoordinate3D<float>& voxel_size,
const bool restrict_to_cylindrical_FOV,
const int num_LORs,
const shared_ptr<const DiscretisedDensity<3,float> >&
density_info_sptr,
const shared_ptr<const ProjDataInfo> proj_data_info_sptr)
const DiscretisedDensity<3, float>& density_info,
const ProjDataInfo& proj_data_info)
{
assert(lor.size() == 0);

Expand Down Expand Up @@ -472,41 +484,14 @@ ray_trace_one_lor(ProjMatrixElemsForOneBin& lor,
// start_point_vx = tx_bed_to_idx(start_point_bed);


CartesianCoordinate3D<float> start_point;
CartesianCoordinate3D<float> stop_point;

// // start and stop point in voxel coordinates
// start_point.x() = (s_in_mm*cphi + max_a*sphi)/voxel_size.x();
// start_point.y() = (s_in_mm*sphi - max_a*cphi)/voxel_size.y();
// start_point.z() = (m_in_mm+offset_in_z - max_a*tantheta)/voxel_size.z();
// stop_point.x() = (s_in_mm*cphi + min_a*sphi)/voxel_size.x();
// stop_point.y() = (s_in_mm*sphi - min_a*cphi)/voxel_size.y();
// stop_point.z() = (m_in_mm+offset_in_z - min_a*tantheta)/voxel_size.z();
// std::cerr << "LOR reference " << start_point << "->" << stop_point << std::endl;

// start and stop point in gantry coordinates
// These are in mm, where (0, 0, 0) is the centre of the gantry
start_point.x() = s_in_mm*cphi + max_a*sphi;
start_point.y() = s_in_mm*sphi - max_a*cphi;
start_point.z() = m_in_mm+offset_in_z - max_a*tantheta;
stop_point.x() = s_in_mm*cphi + min_a*sphi;
stop_point.y() = s_in_mm*sphi - min_a*cphi;
stop_point.z() = m_in_mm+offset_in_z - min_a*tantheta;
// std::cerr << "LOR gantry " << start_point << "->" << stop_point << std::endl;

// Shift to bed coordinates
start_point = density_info_sptr
->get_index_coordinates_for_gantry_coordinates(start_point, proj_data_info_sptr);
stop_point = density_info_sptr
->get_index_coordinates_for_gantry_coordinates(stop_point, proj_data_info_sptr);
// std::cerr << "LOR bedpos " << start_point << "->" << stop_point << std::endl;

// // Shift to Image Index coordinates
// start_point = density_info_sptr
// ->get_index_coordinates_for_physical_coordinates(start_point);
// stop_point = density_info_sptr
// ->get_index_coordinates_for_physical_coordinates(stop_point);
// // std::cerr << "LOR index " << start_point << "->" << stop_point << std::endl;
CartesianCoordinate3D<float> start_point
= get_point_on_lor_in_index_coordinates
(s_in_mm, m_in_mm+offset_in_z, max_a, cphi, sphi, tantheta,
density_info, proj_data_info);
CartesianCoordinate3D<float> stop_point
= get_point_on_lor_in_index_coordinates
(s_in_mm, m_in_mm+offset_in_z, min_a, cphi, sphi, tantheta,
density_info, proj_data_info);

#if 0
// KT 18/05/2005 this is no longer necessary
Expand Down Expand Up @@ -645,11 +630,9 @@ calculate_proj_matrix_elems_for_one_bin(


// find offset in z, taking into account if there are 1 or more LORs
// KT 20/06/2001 take origin.z() into account
// KT 15/05/2002 move +(max_index.z()+min_index.z())/2.F offset here instead of in formulas for Z1f,Z2f
/* Here is how we find the offset of the first ray:
for only 1 ray, it is simply found by refering to the middle of the image
minus the origin.z().
for only 1 ray, it is 0.
For multiple rays, the following reasoning is followed.
First we look at oblique rays.
Expand Down Expand Up @@ -716,7 +699,8 @@ calculate_proj_matrix_elems_for_one_bin(
offset_in_z, fovrad_in_mm,
voxel_size,
restrict_to_cylindrical_FOV,
num_lors_per_axial_pos, density_info_sptr, proj_data_info_sptr);
num_lors_per_axial_pos,
*density_info_sptr, *proj_data_info_sptr);
}
else
{
Expand All @@ -738,7 +722,7 @@ calculate_proj_matrix_elems_for_one_bin(
voxel_size,
restrict_to_cylindrical_FOV,
num_lors_per_axial_pos*num_tangential_LORs,
density_info_sptr, proj_data_info_sptr);
*density_info_sptr, *proj_data_info_sptr);
//std::cerr << "ray traced size " << ray_traced_lor.size() << std::endl;
lor.merge(ray_traced_lor);
}
Expand All @@ -749,37 +733,37 @@ calculate_proj_matrix_elems_for_one_bin(
{
if (tantheta==0 )
{
CartesianCoordinate3D<float>
first_point_of_first_lor(lor.begin()->coord1(),
lor.begin()->coord2(),
lor.begin()->coord3());
// std::cerr << "first_point_of_first_lor: " << first_point_of_first_lor << std::endl;
const float z_of_first_voxel_in_index_space
= first_point_of_first_lor.z();

// In gantry space
CartesianCoordinate3D<float>
start_of_tor_projected_to_axis_without_offset
(m_in_mm - sampling_distance_of_adjacent_LORs_z/2, 0, 0);
CartesianCoordinate3D<float>
end_of_tor_projected_to_axis_without_offset
(m_in_mm + sampling_distance_of_adjacent_LORs_z/2, 0, 0);
// Shift to Image Index coordinates
start_of_tor_projected_to_axis_without_offset = density_info_sptr
->get_index_coordinates_for_gantry_coordinates
(start_of_tor_projected_to_axis_without_offset, proj_data_info_sptr);
end_of_tor_projected_to_axis_without_offset = density_info_sptr
->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
= z_of_first_voxel_in_index_space
- start_of_tor_projected_to_axis_without_offset.z();
const float end_of_tor_relative_to_tor
= end_of_tor_projected_to_axis_without_offset.z()
- start_of_tor_projected_to_axis_without_offset.z();

add_adjacent_z(lor, first_lor_relative_to_tor, end_of_tor_relative_to_tor);
// we want to use add_adjacent_z to fill in mutliple lines
// within the TOR, leveraging our traced LOR

// since tantheta==0, z is constant
const float z_of_traced_lor
= static_cast<float>(lor.begin()->coord1());

// We want the z limits for the TOR. We set s and a to 0.
// Since tantheta==0, they will not affect the z coordinate.
// (actually, as stated above, the LOR has a constant z, and
// so does the TOR)
float z_of_start_of_tor
= get_point_on_lor_in_index_coordinates
(0, m_in_mm - sampling_distance_of_adjacent_LORs_z/2, 0,
cphi, sphi, tantheta,
*density_info_sptr, *proj_data_info_sptr)
.z();
float z_of_end_of_tor
= get_point_on_lor_in_index_coordinates
(0, m_in_mm + sampling_distance_of_adjacent_LORs_z/2, 0,
cphi, sphi, tantheta,
*density_info_sptr, *proj_data_info_sptr)
.z();

const float z_of_traced_lor_relative_to_start_of_tor
= z_of_traced_lor - z_of_start_of_tor;
const float z_of_end_of_tor_relative_to_start_of_tor
= z_of_end_of_tor - z_of_start_of_tor;

add_adjacent_z(lor, z_of_traced_lor_relative_to_start_of_tor,
z_of_end_of_tor_relative_to_start_of_tor);
}
else if (num_lors_per_axial_pos>1)
{
Expand Down

0 comments on commit 02fda25

Please sign in to comment.