17#ifndef __dwi_tractography_algorithms_iFOD1_h__
18#define __dwi_tractography_algorithms_iFOD1_h__
33 namespace Tractography
51 sin_max_angle_1o (std::sin (max_angle_1o)),
54 mean_truncations (0.0),
55 max_max_truncation (0.0),
62 throw Exception (
"Algorithm iFOD1 expects as input a spherical harmonic (SH) image");
71 max_angle_1o = max_angle_ho;
72 cos_max_angle_1o = std::cos (max_angle_1o);
74 cos_max_angle_ho = 0.0;
76 sin_max_angle_1o = std::sin (max_angle_1o);
80 properties[
"method"] =
"iFOD1";
81 properties.set (lmax,
"lmax");
82 properties.set (max_trials,
"max_trials");
83 properties.set (fod_power,
"fod_power");
84 bool precomputed =
true;
85 properties.set (precomputed,
"sh_precomputed");
87 precomputer.init (lmax);
93 mean_samples /= double(num_proc);
94 mean_truncations /= double(num_proc);
95 INFO (
"mean number of samples per step = " +
str (mean_samples));
96 if (mean_truncations) {
97 INFO (
"mean number of steps between rejection sampling truncations = " +
str (1.0/mean_truncations));
98 INFO (
"maximum truncation error = " +
str (max_max_truncation));
100 INFO (
"no rejection sampling truncations occurred");
104 void update_stats (
double mean_samples_per_run,
double mean_truncations_per_run,
double max_truncation)
const
106 mean_samples += mean_samples_per_run;
107 mean_truncations += mean_truncations_per_run;
113 size_t lmax, max_trials;
114 float sin_max_angle_1o, fod_power;
118 mutable double mean_samples, mean_truncations, max_max_truncation;
119 mutable int num_proc;
127 iFOD1 (
const Shared& shared) :
153 if (!
S.init_dir.allFinite()) {
155 const Eigen::Vector3f init_dir (dir);
157 for (
size_t n = 0; n <
S.max_seed_attempts; n++) {
159 float val =
FOD (dir);
160 if (std::isfinite (val))
161 if (val >
S.init_threshold)
168 float val =
FOD (dir);
169 if (std::isfinite (val))
170 if (val >
S.init_threshold)
188 if (std::isnan (val))
190 else if (val > max_val)
201 for (
size_t n = 0; n <
S.max_trials; n++) {
202 Eigen::Vector3f new_dir =
rand_dir (dir);
203 float val =
FOD (new_dir);
205 if (val >
S.threshold) {
207 val = std::pow (val,
S.fod_power);
209 DEBUG (
"max_val exceeded!!! (val = " +
str(val) +
", max_val = " +
str (max_val) +
")");
218 pos +=
S.step_size * dir;
230 float get_metric (
const Eigen::Vector3f& position,
const Eigen::Vector3f& direction)
override
232 if (!get_data (
source, position))
234 return FOD (direction);
246 float FOD (
const Eigen::Vector3f& d)
const
248 return (
S.precomputer ?
249 S.precomputer.value (
values, d) :
270 float operator() (
float el)
277 Eigen::VectorXf& fod;
280 friend void calibrate<iFOD1> (
iFOD1& method);
Eigen::Vector3f rand_dir(const Eigen::Vector3f &d)
Interpolator< Image< float > >::type source
float FOD(const Eigen::Vector3f &d) const
vector< Eigen::Vector3f > calibrate_list
friend void calibrate(iFOD1 &method)
std::uniform_real_distribution< float > uniform
Eigen::Vector3f rotate_direction(const Eigen::Vector3f &reference, const Eigen::Vector3f &direction)
Eigen::Vector3f random_direction()
Precomputed Associated Legrendre Polynomials - used to speed up SH calculation.
void check(const ImageType &H)
convenience function to check if an input image can contain SH coefficients
size_t LforN(int N)
returns the largest lmax given N parameters
VectorType1 & delta(VectorType1 &delta_vec, const VectorType2 &unit_dir, int lmax)
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
const App::OptionGroup iFODOptions
void load_iFOD_options(Tractography::Properties &)
constexpr size_t max_trials_per_step
constexpr float cutoff_fod
constexpr float cutoff_act_multiplier
constexpr float angle_ifod1
constexpr float stepsize_voxels_firstorder
constexpr float stepsize_voxels_rk4
thread_local Math::RNG rng
thread-local, but globally accessible RNG to vastly simplify multi-threading
std::string str(const T &value, int precision=0)