Skip to content
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

Introduce classes for ProjData indices #1273

Merged
merged 6 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions documentation/release_5.2.htm
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ <h3>New functionality</h3>
but you could use it to optimise the number of OpenMP threads to use for your data.
<br /><a href="https://github.com/UCL/STIR/pull/1237/">PR #1237</a>.
</li>
<li>New classes <code>SegmentIndices</code>, <code>ViewgramIndices</code> and <code>SinogramIndices</code>, used by <code>ProjData</code> related classes, as opposed
to having to specify all the elements directly, e.g. in C++
<pre>
auto sinogram = proj_data.get_sinogram(sinogram_indices);
</pre>
This makes these functions more future proof, in particular for TOF. The older functions are now deprecated.
Note that as <code>Bin</code> is now derived from <code>ViewgramIndices</code>, instantations of <code>Bin</code> can now be used to specify the indices as well in most places.
<br/>
There is still more work to do here, mostly related to the symmetries.
<br /><a href="https://github.com/UCL/STIR/pull/1273/">PR #1273</a>.
</li>
</ul>

<h4>Python (and MATLAB)</h4>
Expand Down Expand Up @@ -124,6 +135,11 @@ <h3>Deprecated functionality</h3>
<li>The following functions (previously used for upsampling the scatter estimate) have been
made obsolete or replaced, and will be removed in STIR version 6.0.0: <code>interpolate_axial_position</code>, <code>extend_sinogram_in_views</code> and <code>extend_segment_in_views</code>
</li>
<li>Constructors/functions in <code>ProjData</code> related classes that explicitly use <code>axial_pos_num</code>, <code>view_num</code> etc in their arguments are now deprecated,
and should be replaced by their respective versions that use <code>SegmentIndices</code>, <code>ViewgramIndices</code> or <code>SinogramIndices</code>. The former will not be
compatible with TOF information that will be introduced in version 6.0.0.
</li>
<li>STIR version 6.0.0 will likely require C++ 14 (currently we require C++ 11, but already support C++ 20).</li>
</ul>

<h3>Build system and dependencies</h3>
Expand Down
38 changes: 30 additions & 8 deletions src/buildblock/ProjData.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
#include "stir/IO/GEHDF5Wrapper.h"
#endif
#include "stir/IO/stir_ecat7.h"
#include "stir/ViewSegmentNumbers.h"
#include "stir/ViewgramIndices.h"
#include "stir/is_null_ptr.h"
#include <cstring>
#include <fstream>
Expand Down Expand Up @@ -261,7 +261,19 @@ ProjData::get_subset(const std::vector<int>& views) const
}


Viewgram<float>
Viewgram<float>
ProjData::get_empty_viewgram(const ViewgramIndices& ind) const
{
return proj_data_info_sptr->get_empty_viewgram(ind);
}

Sinogram<float>
ProjData::get_empty_sinogram(const SinogramIndices& ind) const
{
return proj_data_info_sptr->get_empty_sinogram(ind);
}

Viewgram<float>
ProjData::get_empty_viewgram(const int view_num, const int segment_num,
const bool make_num_tangential_poss_odd) const
{
Expand Down Expand Up @@ -296,9 +308,20 @@ ProjData::get_empty_segment_by_view(const int segment_num,

}

RelatedViewgrams<float>
ProjData::get_empty_related_viewgrams(const ViewSegmentNumbers& view_segmnet_num,
//const int view_num, const int segment_num,
SegmentBySinogram<float>
ProjData::get_empty_segment_by_sinogram(const SegmentIndices& ind) const
{
return proj_data_info_sptr->get_empty_segment_by_sinogram(ind);
}

SegmentByView<float>
ProjData::get_empty_segment_by_view(const SegmentIndices& ind) const
{
return proj_data_info_sptr->get_empty_segment_by_view(ind);
}

RelatedViewgrams<float>
ProjData::get_empty_related_viewgrams(const ViewgramIndices& view_segmnet_num,
const shared_ptr<DataSymmetriesForViewSegmentNumbers>& symmetries_used,
const bool make_num_tangential_poss_odd) const
{
Expand All @@ -308,15 +331,14 @@ ProjData::get_empty_related_viewgrams(const ViewSegmentNumbers& view_segmnet_num


RelatedViewgrams<float>
ProjData::get_related_viewgrams(const ViewSegmentNumbers& view_segmnet_num,
//const int view_num, const int segment_num,
ProjData::get_related_viewgrams(const ViewgramIndices& viewgram_indices,
const shared_ptr<DataSymmetriesForViewSegmentNumbers>& symmetries_used,
const bool make_num_bins_odd) const
{
vector<ViewSegmentNumbers> pairs;
symmetries_used->get_related_view_segment_numbers(
pairs,
ViewSegmentNumbers(view_segmnet_num.view_num(),view_segmnet_num.segment_num())
viewgram_indices
);

vector<Viewgram<float> > viewgrams;
Expand Down
50 changes: 41 additions & 9 deletions src/buildblock/ProjDataInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Copyright (C) 2000 PARAPET partners
Copyright (C) 2000 - 2009-05-13, Hammersmith Imanet Ltd
Copyright (C) 2011-07-01 - 2011, Kris Thielemans
Copyright (C) 2018, 2022, University College London
Copyright (C) 2018, 2022, 2023, University College London
Copyright (C) 2018, University of Leeds
This file is part of STIR.

Expand Down Expand Up @@ -262,6 +262,15 @@ ProjDataInfo::get_empty_viewgram(const int view_num,
return v;
}

Viewgram<float>
ProjDataInfo::get_empty_viewgram(const ViewgramIndices& ind) const
{
// we can't access the shared ptr, so we have to clone 'this'.
shared_ptr<ProjDataInfo> proj_data_info_sptr(this->clone());
Viewgram<float> v(proj_data_info_sptr, ind);
return v;
}


Sinogram<float>
ProjDataInfo::get_empty_sinogram(const int axial_pos_num, const int segment_num,
Expand All @@ -278,6 +287,15 @@ ProjDataInfo::get_empty_sinogram(const int axial_pos_num, const int segment_num,
return s;
}

Sinogram<float>
ProjDataInfo::get_empty_sinogram(const SinogramIndices& ind) const
{
// we can't access the shared ptr, so we have to clone 'this'.
shared_ptr<ProjDataInfo> proj_data_info_sptr(this->clone());
Sinogram<float> s(proj_data_info_sptr, ind);
return s;
}

SegmentBySinogram<float>
ProjDataInfo::get_empty_segment_by_sinogram(const int segment_num,
const bool make_num_tangential_poss_odd) const
Expand All @@ -296,6 +314,14 @@ ProjDataInfo::get_empty_segment_by_sinogram(const int segment_num,
return s;
}

SegmentBySinogram<float>
ProjDataInfo::get_empty_segment_by_sinogram(const SegmentIndices& ind) const
{
// we can't access the shared ptr, so we have to clone 'this'.
shared_ptr<ProjDataInfo> proj_data_info_sptr(this->clone());
SegmentBySinogram<float> s(proj_data_info_sptr, ind);
return s;
}

SegmentByView<float>
ProjDataInfo::get_empty_segment_by_view(const int segment_num,
Expand All @@ -315,26 +341,32 @@ ProjDataInfo::get_empty_segment_by_view(const int segment_num,
return s;
}

SegmentByView<float>
ProjDataInfo::get_empty_segment_by_view(const SegmentIndices& ind) const
{
// we can't access the shared ptr, so we have to clone 'this'.
shared_ptr<ProjDataInfo> proj_data_info_sptr(this->clone());
SegmentByView<float> s(proj_data_info_sptr, ind);
return s;
}

RelatedViewgrams<float>
ProjDataInfo::get_empty_related_viewgrams(const ViewSegmentNumbers& view_segmnet_num,
//const int view_num, const int segment_num,
ProjDataInfo::get_empty_related_viewgrams(const ViewgramIndices& viewgram_indices,
const shared_ptr<DataSymmetriesForViewSegmentNumbers>& symmetries_used,
const bool make_num_tangential_poss_odd) const
{
if (make_num_tangential_poss_odd)
error("make_num_tangential_poss_odd is no longer supported");
vector<ViewSegmentNumbers> pairs;
symmetries_used->get_related_view_segment_numbers(
pairs,
ViewSegmentNumbers(view_segmnet_num.view_num(),view_segmnet_num.segment_num())
);
symmetries_used->get_related_view_segment_numbers(pairs, viewgram_indices);

vector<Viewgram<float> > viewgrams;
viewgrams.reserve(pairs.size());

for (unsigned int i=0; i<pairs.size(); i++)
{
// TODO optimise to get shared proj_data_info_ptr
viewgrams.push_back(get_empty_viewgram(pairs[i].view_num(),
pairs[i].segment_num(), make_num_tangential_poss_odd));
viewgrams.push_back(get_empty_viewgram(pairs[i]));
}

return RelatedViewgrams<float>(viewgrams, symmetries_used);
Expand Down
35 changes: 26 additions & 9 deletions src/buildblock/SegmentBySinogram.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,55 @@ template <typename elemT>
SegmentBySinogram<elemT> ::
SegmentBySinogram(const Array<3,elemT>& v,
const shared_ptr<const ProjDataInfo>& pdi_ptr,
const int segment_num)
const SegmentIndices& ind)
:
Segment<elemT>(pdi_ptr, segment_num),
Segment<elemT>(pdi_ptr, ind),
Array<3,elemT>(v)
{
assert( get_min_view_num() == pdi_ptr->get_min_view_num());
assert( get_max_view_num() == pdi_ptr->get_max_view_num());
assert( get_min_axial_pos_num() == pdi_ptr->get_min_axial_pos_num(segment_num));
assert( get_max_axial_pos_num() == pdi_ptr->get_max_axial_pos_num(segment_num));
assert( get_min_axial_pos_num() == pdi_ptr->get_min_axial_pos_num(ind.segment_num()));
assert( get_max_axial_pos_num() == pdi_ptr->get_max_axial_pos_num(ind.segment_num()));
assert( get_min_tangential_pos_num() == pdi_ptr->get_min_tangential_pos_num());
assert( get_max_tangential_pos_num() == pdi_ptr->get_max_tangential_pos_num());
}

template <typename elemT>
SegmentBySinogram<elemT> ::
SegmentBySinogram(const shared_ptr<const ProjDataInfo>& pdi_ptr,
const int segment_num)
const SegmentIndices& ind)
:
Segment<elemT>(pdi_ptr, segment_num),
Array<3,elemT>(IndexRange3D(pdi_ptr->get_min_axial_pos_num(segment_num),
pdi_ptr->get_max_axial_pos_num(segment_num),
Segment<elemT>(pdi_ptr, ind),
Array<3,elemT>(IndexRange3D(pdi_ptr->get_min_axial_pos_num(ind.segment_num()),
pdi_ptr->get_max_axial_pos_num(ind.segment_num()),
pdi_ptr->get_min_view_num(),
pdi_ptr->get_max_view_num(),
pdi_ptr->get_min_tangential_pos_num(),
pdi_ptr->get_max_tangential_pos_num()))
{}

template <typename elemT>
SegmentBySinogram<elemT>::
SegmentBySinogram(const Array<3,elemT>& v,
const shared_ptr<const ProjDataInfo>& pdi_sptr,
int segment_num)
:
SegmentBySinogram(v, pdi_sptr, SegmentIndices(segment_num))
{}

template <typename elemT>
SegmentBySinogram<elemT>::
SegmentBySinogram(const shared_ptr<const ProjDataInfo>& pdi_sptr,
const int segment_num)
:
SegmentBySinogram(pdi_sptr, SegmentIndices(segment_num))
{}

template <typename elemT>
SegmentBySinogram<elemT>::
SegmentBySinogram(const SegmentByView<elemT>& s_v )
: Segment<elemT>(s_v.get_proj_data_info_sptr()->create_shared_clone(),
s_v.get_segment_num()),
s_v.get_segment_indices()),
Array<3,elemT> (IndexRange3D (s_v.get_min_axial_pos_num(), s_v.get_max_axial_pos_num(),
s_v.get_min_view_num(), s_v.get_max_view_num(),
s_v.get_min_tangential_pos_num(), s_v.get_max_tangential_pos_num()))
Expand Down
35 changes: 25 additions & 10 deletions src/buildblock/SegmentByView.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ template <typename elemT>
SegmentByView<elemT>::
SegmentByView(const Array<3,elemT>& v,
const shared_ptr<const ProjDataInfo>& pdi_ptr,
const int segment_num)
const SegmentIndices& ind)
:
Segment<elemT>(pdi_ptr, segment_num),
Segment<elemT>(pdi_ptr, ind),
Array<3,elemT>(v)
{
assert( get_min_view_num() == pdi_ptr->get_min_view_num());
assert( get_max_view_num() == pdi_ptr->get_max_view_num());
assert( get_min_axial_pos_num() == pdi_ptr->get_min_axial_pos_num(segment_num));
assert( get_max_axial_pos_num() == pdi_ptr->get_max_axial_pos_num(segment_num));
assert( get_min_axial_pos_num() == pdi_ptr->get_min_axial_pos_num(ind.segment_num()));
assert( get_max_axial_pos_num() == pdi_ptr->get_max_axial_pos_num(ind.segment_num()));
assert( get_min_tangential_pos_num() == pdi_ptr->get_min_tangential_pos_num());
assert( get_max_tangential_pos_num() == pdi_ptr->get_max_tangential_pos_num());

Expand All @@ -50,22 +50,37 @@ SegmentByView(const Array<3,elemT>& v,
template <typename elemT>
SegmentByView<elemT>::
SegmentByView(const shared_ptr<const ProjDataInfo>& pdi_ptr,
const int segment_num)
const SegmentIndices& ind)
:
Segment<elemT>(pdi_ptr, segment_num),
Segment<elemT>(pdi_ptr, ind),
Array<3,elemT>(IndexRange3D(pdi_ptr->get_min_view_num(),
pdi_ptr->get_max_view_num(),
pdi_ptr->get_min_axial_pos_num(segment_num),
pdi_ptr->get_max_axial_pos_num(segment_num),
pdi_ptr->get_min_axial_pos_num(ind.segment_num()),
pdi_ptr->get_max_axial_pos_num(ind.segment_num()),
pdi_ptr->get_min_tangential_pos_num(),
pdi_ptr->get_max_tangential_pos_num()))
{}

template <typename elemT>
SegmentByView<elemT>::
SegmentByView(const Array<3,elemT>& v,
const shared_ptr<const ProjDataInfo>& pdi_sptr,
const int segment_num)
:
SegmentByView(v, pdi_sptr, SegmentIndices(segment_num))
{}

template <typename elemT>
SegmentByView<elemT>::
SegmentByView(const shared_ptr<const ProjDataInfo>& pdi_sptr,
const int segment_num)
: SegmentByView(pdi_sptr, SegmentIndices(segment_num))
{}

template <typename elemT>
SegmentByView<elemT>::SegmentByView(const SegmentBySinogram<elemT>& s_s)
: Segment<elemT>(s_s.get_proj_data_info_sptr()->create_shared_clone(),
s_s.get_segment_num()),

s_s.get_segment_indices()),
Array<3,elemT> (IndexRange3D(s_s.get_min_view_num(),s_s.get_max_view_num(),
s_s.get_min_axial_pos_num(),s_s.get_max_axial_pos_num(),
s_s.get_min_tangential_pos_num(), s_s.get_max_tangential_pos_num()))
Expand Down
16 changes: 5 additions & 11 deletions src/include/stir/Bin.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/*
Copyright (C) 2000 PARAPET partners
Copyright (C) 2000- 2009, Hammersmith Imanet Ltd
Copyright (C) 2023, University College London
This file is part of STIR.

SPDX-License-Identifier: Apache-2.0 AND License-ref-PARAPET-license
Expand All @@ -27,7 +28,7 @@
#define __stir_Bin_H__


#include "stir/common.h"
#include "stir/ViewgramIndices.h"


START_NAMESPACE_STIR
Expand All @@ -39,10 +40,11 @@ START_NAMESPACE_STIR
handling list mode data.
*/

class Bin
class Bin : public ViewgramIndices
{
typedef ViewgramIndices base_type;
public:
//! default constructor
//! default constructor (leaves most members uninitialised)
inline Bin();

//! A constructor : constructs a bin with value (defaulting to 0)
Expand All @@ -51,19 +53,13 @@ class Bin

//!get axial position number
inline int axial_pos_num()const;
//! get segmnet number
inline int segment_num()const;
//! get tangential position number
inline int tangential_pos_num() const;
//! get view number
inline int view_num() const;
//! get time-frame number (1-based)
inline int time_frame_num() const;

inline int& axial_pos_num();
inline int& segment_num();
inline int& tangential_pos_num();
inline int& view_num();
inline int& time_frame_num();


Expand Down Expand Up @@ -91,8 +87,6 @@ class Bin
private :
// shared_ptr<ProjDataInfo> proj_data_info_ptr;

int segment;
KrisThielemans marked this conversation as resolved.
Show resolved Hide resolved
int view;
int axial_pos;
int tangential_pos;
float bin_value;
Expand Down
Loading