17#ifndef __dwi_tractography_roi_h__
18#define __dwi_tractography_roi_h__
32 namespace Tractography
43 using transform_type = Eigen::Transform<float, 3, Eigen::AffineCompact>;
50 std::shared_ptr<transform_type> scanner2voxel, voxel2scanner;
61 ROI (
const Eigen::Vector3f& sphere_pos,
float sphere_radius) :
62 pos (sphere_pos), radius (sphere_radius), radius2 (
Math::pow2 (radius)) { }
64 ROI (
const std::string& spec) :
65 radius (
NaN), radius2 (
NaN)
79 mask.reset (
new Mask (spec));
81 Exception e (
"Unable to parse text \"" + spec +
"\" as a ROI");
82 e.push_back (
"If interpreted as sphere:");
83 for (
size_t i = 0; i != e_assphere.
num(); ++i)
84 e.push_back (
" " + e_assphere[i]);
85 e.push_back (
"If interpreted as image:");
86 for (
size_t i = 0; i != e_asimage.
num(); ++i)
87 e.push_back (
" " + e_asimage[i]);
93 std::string shape ()
const {
return (mask ?
"image" :
"sphere"); }
95 std::string parameters ()
const {
98 str(pos[0]) +
"," +
str(pos[1]) +
"," +
str(pos[2]) +
"," +
str(radius);
101 float min_featurelength()
const {
103 std::min ({ mask->spacing(0), mask->spacing(1), mask->spacing(2) }) :
107 bool contains (
const Eigen::Vector3f& p)
const
110 Eigen::Vector3f v = *(mask->scanner2voxel) * p;
115 if (is_out_of_bounds (temp))
119 return (pos-p).squaredNorm() <= radius2;
122 friend inline std::ostream&
operator<< (std::ostream& stream,
const ROI& roi)
124 stream << roi.shape() <<
" (" << roi.parameters() <<
")";
132 float radius, radius2;
133 std::shared_ptr<Mask> mask;
145 void clear () {
R.clear(); }
146 size_t size ()
const {
return (
R.size()); }
147 const ROI& operator[] (
size_t i)
const {
return (
R[i]); }
148 void add (
const ROI& roi) {
R.push_back (roi); }
151 if (
R.R.empty())
return (stream);
155 for (; i !=
R.R.end(); ++i) stream <<
", " << *i;
170 bool contains (
const Eigen::Vector3f& p)
const {
171 for (
size_t n = 0; n <
R.size(); ++n)
172 if (
R[n].contains (p))
return (
true);
175 void contains (
const Eigen::Vector3f& p,
BitSet& retval)
const {
176 for (
size_t n = 0; n <
R.size(); ++n)
177 if (
R[n].contains (p)) retval[n] =
true;
193 size (master.size()),
196 LoopState (
const size_t num_rois) :
201 void reset() { valid =
true; next_index = 0; }
202 operator bool ()
const {
return valid; }
204 void operator() (
const size_t roi_index)
206 assert (roi_index < size);
207 if (roi_index == next_index)
209 else if (roi_index != next_index - 1)
213 bool all_entered()
const {
return (valid && (next_index == size)); }
223 void contains (
const Eigen::Vector3f& p, LoopState& loop_state)
const
228 for (
size_t n = 0; n <
R.size(); ++n) {
229 if (
R[n].contains(p)) {
258 void operator() (
const Eigen::Vector3f& p)
265 bool operator! ()
const {
return (!
visited.
full() || !
state.all_entered()); }
a class for storing bitwise information
void clear(const bool allocator=false)
clear the data
bool full() const
whether or not the bitset is 'full' i.e. all elements are true
const ROIOrderedSet & ordered
ROIOrderedSet::LoopState state
const ROIUnorderedSet & unordered
friend std::ostream & operator<<(std::ostream &stream, const ROI &roi)
friend std::ostream & operator<<(std::ostream &stream, const ROISetBase &R)
functions and classes related to image data input/output
const std::string & name() const
constexpr T pow2(const T &v)
constexpr I round(const T x)
void load_rois(Properties &properties)
const App::OptionGroup ROIOption
vector< default_type > parse_floats(const std::string &spec)
std::string str(const T &value, int precision=0)
Eigen::Transform< default_type, 3, Eigen::AffineCompact > transform_type
the type for the affine transform of an image:
constexpr default_type NaN