Developer documentation
Version 3.0.3-105-gd3941f44
tensor_det.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __dwi_tractography_algorithms_tensor_det_h__
18#define __dwi_tractography_algorithms_tensor_det_h__
19
20// These lines are to silence deprecation warnings with Eigen & GCC v5
21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
23#include <Eigen/Eigenvalues>
24#pragma GCC diagnostic pop
25
26#include "math/least_squares.h"
27#include "dwi/gradient.h"
28#include "dwi/tensor.h"
33
34
35
36namespace MR
37{
38 namespace DWI
39 {
40 namespace Tractography
41 {
42 namespace Algorithms
43 {
44
45
46 using namespace MR::DWI::Tractography::Tracking;
47
48
50 public:
51 class Shared : public SharedBase { MEMALIGN(Shared)
52 public:
53 Shared (const std::string& diff_path, DWI::Tractography::Properties& property_set) :
54 SharedBase (diff_path, property_set) {
55
56 if (is_act() && act().backtrack())
57 throw Exception ("Backtracking not valid for deterministic algorithms");
58
61 rk4);
62 set_num_points();
63 set_cutoff (Defaults::cutoff_fa * (is_act() ? Defaults::cutoff_act_multiplier : 1.0));
64
65 properties["method"] = "TensorDet";
66
67 try {
68 auto grad = DWI::get_DW_scheme (source);
69 auto bmat_double = grad2bmatrix<double> (grad);
70 binv = Math::pinv (bmat_double).cast<float>();
71 bmat = bmat_double.cast<float>();
72 } catch (Exception& e) {
73 e.display();
74 throw Exception ("Tensor-based tracking algorithms expect a DWI series as input");
75 }
76 }
77
78 Eigen::MatrixXf bmat, binv;
79 };
80
81
82
83
84
85
86 Tensor_Det (const Shared& shared) :
87 MethodBase (shared),
88 S (shared),
89 source (S.source),
90 eig (3),
91 M (3,3),
92 dt (6) { }
93
94
95
96
97
98 bool init() override
99 {
100 if (!get_data (source))
101 return false;
102 if (!do_init())
103 return false;
104 if (S.init_dir.allFinite())
105 return true;
106 if (S.init_dir.dot (dir) < 0.0)
107 dir = -dir;
108 return true;
109 }
110
111
112
113 term_t next () override
114 {
115 if (!get_data (source))
116 return EXIT_IMAGE;
117 return do_next();
118 }
119
120
121 float get_metric (const Eigen::Vector3f& position, const Eigen::Vector3f& direction) override
122 {
123 if (!get_data (source, position))
124 return 0.0;
125 dwi2tensor (dt, S.binv, values);
126 return tensor2FA (dt);
127 }
128
129
130 protected:
131 const Shared& S;
133 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eig;
134 Eigen::Matrix3f M;
135 Eigen::VectorXf dt;
136
137 void get_EV ()
138 {
139 M(0,0) = dt[0];
140 M(1,1) = dt[1];
141 M(2,2) = dt[2];
142 M(1,0) = M(0,1) = dt[3];
143 M(2,0) = M(0,2) = dt[4];
144 M(2,1) = M(1,2) = dt[5];
145
146 eig.computeDirect (M);
147 dir = eig.eigenvectors().col(2);
148 }
149
150
151 bool do_init()
152 {
153 dwi2tensor (dt, S.binv, values);
154
155 if (tensor2FA (dt) < S.init_threshold)
156 return false;
157
158 get_EV();
159
160 return true;
161 }
162
163
165 {
166
167 dwi2tensor (dt, S.binv, values);
168
169 if (tensor2FA (dt) < S.threshold)
170 return MODEL;
171
172 Eigen::Vector3f prev_dir = dir;
173
174 get_EV();
175
176 float dot = prev_dir.dot (dir);
177 if (abs (dot) < S.cos_max_angle_1o)
178 return HIGH_CURVATURE;
179
180 if (dot < 0.0)
181 dir = -dir;
182
183 pos += dir * S.step_size;
184
185 return CONTINUE;
186
187 }
188
189
190 };
191
192 }
193 }
194 }
195}
196
197#endif
198
199
Eigen::SelfAdjointEigenSolver< Eigen::Matrix3f > eig
Definition: tensor_det.h:133
Tracking::Interpolator< Image< float > >::type source
Definition: tensor_det.h:132
Eigen::Matrix< typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic > pinv(const MatrixType &M)
return Moore-Penrose pseudo-inverse of M
Definition: least_squares.h:39
constexpr double e
Definition: math.h:39
Eigen::MatrixXd get_DW_scheme(const Header &header, BValueScalingBehaviour bvalue_scaling=BValueScalingBehaviour::Auto)
get the fully-interpreted DW gradient encoding matrix
void dwi2tensor(VectorTypeOut &dt, const MatrixType &binv, VectorTypeIn &dwi)
Definition: tensor.h:79
VectorType::Scalar tensor2FA(const VectorType &dt)
Definition: tensor.h:95
Definition: base.h:24
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)
Definition: types.h:297
#define MEMALIGN(...)
Definition: types.h:185