17#ifndef __dwi_gradient_h__
18#define __dwi_gradient_h__
32 namespace App {
class OptionGroup; }
49 template <
class MatrixType>
53 throw Exception (
"no valid diffusion gradient table found");
55 throw Exception (
"unexpected diffusion gradient table matrix dimensions");
57 if (header.ndim() >= 4) {
58 if (header.size (3) != (
int) grad.rows())
59 throw Exception (
"number of studies in base image (" +
str(header.size(3))
60 +
") does not match number of rows in diffusion gradient table (" +
str(grad.rows()) +
")");
62 else if (grad.rows() != 1)
63 throw Exception (
"For images with less than four dimensions, gradient table can have one row only");
74 template <
class MatrixType,
class IndexVectorType>
76 const MatrixType& grad,
77 const IndexVectorType&
dwi)
79 Eigen::MatrixXd dirs (
dwi.size(),2);
80 for (
size_t i = 0; i <
dwi.size(); i++) {
81 dirs (i,0) = std::atan2 (grad (
dwi[i],1), grad (
dwi[i],0));
82 auto z = grad (
dwi[i],2) / grad.row (
dwi[i]).template head<3>().norm();
88 dirs (i,1) = std::acos (z);
97 template <
class MatrixType>
101 if (dirs.cols() == 2)
134 template <
class MatrixType>
135 std::string scheme2str (
const MatrixType& G)
137 std::string dw_scheme;
138 for (ssize_t row = 0; row < G.rows(); ++row) {
139 std::string line =
str(G(row,0), 10);
140 for (ssize_t col = 1; col < G.cols(); ++col)
141 line +=
"," +
str(G(row,col), 10);
154 template <
class MatrixType>
158 auto it = header.keyval().find (
"dw_scheme");
159 if (it != header.keyval().end())
160 header.keyval().erase (it);
165 header.keyval()[
"dw_scheme"] = scheme2str (G);
167 WARN (
"attempt to add non-matching DW scheme to header - ignored");
211 template <
class MatrixType>
216 header.keyval()[
"prior_dw_scheme"] = scheme2str (grad);
263 template <
class MatrixType>
265 const MatrixType& directions,
266 bool lmax_from_command_line =
true,
267 int default_lmax = 8)
271 bool lmax_set_from_commandline =
false;
272 if (lmax_from_command_line) {
275 lmax_set_from_commandline =
true;
276 lmax = to<int> (opt[0][0]);
278 throw Exception (
"lmax must be an even number");
280 throw Exception (
"lmax must be a non-negative number");
281 if (lmax > lmax_from_ndir) {
282 WARN (
"not enough directions for lmax = " +
str(lmax) +
" - dropping down to " +
str(lmax_from_ndir));
283 lmax = lmax_from_ndir;
289 lmax = lmax_from_ndir;
290 if (lmax > default_lmax)
294 INFO (
"computing SH transform using lmax = " +
str (lmax));
296 int lmax_prev = lmax;
297 Eigen::MatrixXd mapping;
303 WARN (
"directions are poorly distributed for lmax = " +
str(lmax) +
" (condition number = " +
str (cond) +
")");
304 if (cond < 100.0 || lmax_set_from_commandline)
309 if (lmax_prev != lmax)
310 WARN (
"reducing lmax to " +
str(lmax) +
" to improve conditioning");
325 const bool lmax_from_command_line =
true,
326 const int default_lmax = 8)
a class to hold a named list of Option's
A class to specify a command-line option.
size_t LforN(int N)
returns the largest lmax given N parameters
Eigen::Matrix< typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic > init_transform(const MatrixType &dirs, const int lmax)
form the SH->amplitudes matrix
const vector< ParsedOption > get_options(const std::string &name)
return all command-line options matching name
void stash_DW_scheme(Header &header, const MatrixType &grad)
'stash' the DW gradient table
Eigen::MatrixXd compute_SH2amp_mapping(const MatrixType &directions, bool lmax_from_command_line=true, int default_lmax=8)
get the matrix mapping SH coefficients to amplitudes
Eigen::MatrixXd get_raw_DW_scheme(const Header &header)
get the DW scheme as found in the headers or supplied at the command-line
App::Option bvalue_scaling_option
void save_bvecs_bvals(const Header &, const std::string &, const std::string &)
export gradient table in FSL format (bvecs/bvals)
void set_DW_scheme(Header &header, const MatrixType &G)
store the DW gradient encoding matrix in a header
size_t lmax_for_directions(const Eigen::MatrixXd &directions, const bool lmax_from_command_line=true, const int default_lmax=8)
get the maximum spherical harmonic order given a set of directions
void export_grad_commandline(const Header &header)
process GradExportOptions command-line options
App::OptionGroup GradImportOptions()
Eigen::MatrixXd parse_DW_scheme(const Header &header)
parse the DW gradient encoding matrix from a header
Eigen::MatrixXd load_bvecs_bvals(const Header &header, const std::string &bvecs_path, const std::string &bvals_path)
load and rectify FSL-style bvecs/bvals DW encoding files
BValueScalingBehaviour get_cmdline_bvalue_scaling_behaviour()
const char *const bvalue_scaling_description
default_type condition_number_for_lmax(const MatrixType &dirs, int lmax)
Eigen::MatrixXd get_DW_scheme(const Header &header, BValueScalingBehaviour bvalue_scaling=BValueScalingBehaviour::Auto)
get the fully-interpreted DW gradient encoding matrix
App::OptionGroup GradExportOptions()
void clear_DW_scheme(Header &)
clear any DW gradient encoding scheme from the header
void check_DW_scheme(const Header &header, const MatrixType &grad)
check that the DW scheme matches the DWI data in header
Eigen::MatrixXd gen_direction_matrix(const MatrixType &grad, const IndexVectorType &dwi)
convert the DW encoding matrix in grad into a azimuth/elevation direction set, using only the DWI vol...
std::enable_if< VectorType1::IsVectorAtCompileTime, void >::type cartesian2spherical(const VectorType1 &xyz, VectorType2 &&az_el_r)
convert Cartesian coordinates to spherical coordinates
default_type condition_number(const M &data)
double default_type
the default type used throughout MRtrix
std::string str(const T &value, int precision=0)
std::string & add_line(std::string &original, const std::string &new_line)
add a line to a string, taking care of inserting a newline if needed