31#define FMLS_INTEGRAL_THRESHOLD_DEFAULT 0.0
32#define FMLS_PEAK_VALUE_THRESHOLD_DEFAULT 0.1
33#define FMLS_MERGE_RATIO_BRIDGE_TO_PEAK_DEFAULT 1.0
69 values (Eigen::Array<default_type, Eigen::Dynamic, 1>::Zero (dirs.size())),
71 peak_dirs (1, dirs.get_dir (seed)),
72 mean_dir (peak_dirs.front() *
abs(
value) * weight),
84 values (Eigen::Array<default_type, Eigen::Dynamic, 1>::Zero (i.
size())),
92 assert ((
value <= 0.0 && neg) || (
value >= 0.0 && !neg));
95 const Eigen::Vector3d& dir = mask.
get_dirs()[bin];
96 const default_type multiplier = (mean_dir.dot (dir)) > 0.0 ? 1.0 : -1.0;
97 mean_dir += dir * multiplier *
abs(
value) * weight;
101 void revise_peak (
const size_t index,
const Eigen::Vector3d& revised_peak_dir,
const default_type revised_peak_value)
104 assert (
index < num_peaks());
105 peak_dirs[
index] = revised_peak_dir;
107 max_peak_value = revised_peak_value;
110#ifdef FMLS_OPTIMISE_MEAN_DIR
111 void revise_mean_dir (
const Eigen::Vector3f& real_mean)
114 mean_dir = real_mean;
121 mean_dir.normalize();
126 assert (neg == that.neg);
128 for (
size_t i = 0; i != mask.
size(); ++i)
129 values[i] += that.values[i];
130 if (that.max_peak_value > max_peak_value) {
131 max_peak_value = that.max_peak_value;
132 peak_dirs.insert (peak_dirs.begin(), that.peak_dirs.begin(), that.peak_dirs.end());
134 peak_dirs.insert (peak_dirs.end(), that.peak_dirs.begin(), that.peak_dirs.end());
136 const default_type multiplier = (mean_dir.dot (that.mean_dir)) > 0.0 ? 1.0 : -1.0;
137 mean_dir += that.mean_dir * that.integral * multiplier;
138 integral += that.integral;
142 const Eigen::Array<default_type, Eigen::Dynamic, 1>& get_values()
const {
return values; }
143 default_type get_max_peak_value()
const {
return max_peak_value; }
144 size_t num_peaks()
const {
return peak_dirs.size(); }
145 const Eigen::Vector3d& get_peak_dir (
const size_t i)
const { assert (i < num_peaks());
return peak_dirs[i]; }
146 const Eigen::Vector3d& get_mean_dir()
const {
return mean_dir; }
148 bool is_negative()
const {
return neg; }
153 Eigen::Array<default_type, Eigen::Dynamic, 1> values;
156 Eigen::Vector3d mean_dir;
175 SH_coefs (
const Eigen::Matrix<default_type, Eigen::Dynamic, 1>& that) :
176 Eigen::Matrix<default_type, Eigen::Dynamic, 1> (that),
191 loop (
Loop(
"segmenting FODs", 0, 3) (fod)) { }
199 assign_pos_of (fod, 0, 3).to (mask);
202 }
while (loop && !mask.value());
204 assign_pos_of (fod).to (out.vox);
205 out.resize (fod.size (3));
206 for (
auto l =
Loop (3) (fod); l; ++l)
207 out[fod.index(3)] = fod.value();
215 decltype(
Loop(
"text", 0, 3) (fod)) loop;
227 default_type operator[] (
const size_t i) { assert (i <
size_t(data.size()));
return data[i]; }
229 Eigen::Array<default_type, Eigen::Dynamic, 1> data;
243 default_type get_integral_threshold ()
const {
return integral_threshold; }
244 void set_integral_threshold (
const default_type i) { integral_threshold = i; }
245 default_type get_peak_value_threshold ()
const {
return peak_value_threshold; }
246 void set_peak_value_threshold (
const default_type i) { peak_value_threshold = i; }
247 default_type get_lobe_merge_ratio ()
const {
return lobe_merge_ratio; }
248 void set_lobe_merge_ratio (
const default_type i) { lobe_merge_ratio = i; }
249 bool get_create_null_lobe ()
const {
return create_null_lobe; }
250 void set_create_null_lobe (
const bool i) { create_null_lobe = i; verify_settings(); }
251 bool get_create_lookup_table ()
const {
return create_lookup_table; }
252 void set_create_lookup_table (
const bool i) { create_lookup_table = i; verify_settings(); }
253 bool get_dilate_lookup_table ()
const {
return dilate_lookup_table; }
254 void set_dilate_lookup_table (
const bool i) { dilate_lookup_table = i; verify_settings(); }
266 std::shared_ptr<Math::SH::Transform <default_type>> transform;
267 std::shared_ptr<Math::SH::PrecomputedAL<default_type>> precomputer;
268 std::shared_ptr<IntegrationWeights> weights;
273 bool create_null_lobe;
274 bool create_lookup_table;
275 bool dilate_lookup_table;
278 void verify_settings()
const
280 if (create_null_lobe && dilate_lookup_table)
281 throw Exception (
"For FOD segmentation, options 'create_null_lobe' and 'dilate_lookup_table' are mutually exclusive");
282 if (!create_lookup_table && dilate_lookup_table)
283 throw Exception (
"For FOD segmentation, 'create_lookup_table' must be set in order for lookup tables to be dilated ('dilate_lookup_table')");
286#ifdef FMLS_OPTIMISE_MEAN_DIR
287 void optimise_mean_dir (
FOD_lobe&)
const;
a class to hold a named list of Option's
size_t size() const
the number of boolean elements in the set
const Set & get_dirs() const
FODQueueWriter(const FODImageType &fod_image, const MaskImageType &mask_image=MaskImageType())
bool operator()(SH_coefs &out)
Matrix(const MR::Helper::ConstRow< ImageType > &row)
FORCE_INLINE LoopAlongAxes Loop()
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
void load_fmls_thresholds(Segmenter &)
const App::OptionGroup FMLSSegmentOption
double default_type
the default type used throughout MRtrix
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)