Developer documentation
Version 3.0.3-105-gd3941f44
linear.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 __registration_linear_h__
18#define __registration_linear_h__
19
20#include <iostream>
21
22#include "app.h"
23#include "image.h"
24#include "types.h"
25#include "math/average_space.h"
26#include "filter/normalise.h"
27#include "filter/resize.h"
28#include "filter/reslice.h"
29#include "adapter/reslice.h"
30#include "algo/threaded_loop.h"
31#include "interp/linear.h"
32#include "interp/nearest.h"
34// #include "registration/metric/local_cross_correlation.h"
39// #include "math/check_gradient.h"
40#include "math/rng.h"
41#include "math/math.h"
42
45
46namespace MR
47{
48 namespace Registration
49 {
50
55 extern const App::OptionGroup fod_options;
56 extern const char* optim_algo_names[];
57
61
62
64 StageSetting() :
66 gd_max_iter (500),
67 scale_factor (1.0),
72 loop_density (1.0),
73 fod_lmax (-1) {}
74
75 std::string info (const bool& do_reorientation = true) {
76 std::string st;
77 st = "scale factor " + str(scale_factor, 3);
78 if (do_reorientation)
79 st += ", lmax " + str(fod_lmax);
80 st += ", GD max_iter " + str(gd_max_iter);
81 if (loop_density < 1.0)
82 st += ", GD density: " + str(loop_density);
83 if (stage_iterations > 1)
84 st += ", iterations: " + str(stage_iterations);
85 st += ", optimiser: ";
86 for (auto & optim : optimisers) {
87 st += str(optim_algo_names[optim]) + " ";
88 }
89 return st;
90 }
96 ssize_t fod_lmax;
98 } ;
99
101
102 public:
103
105
106 Linear () :
107 stages (3),
108 kernel_extent (3, 1),
109 grad_tolerance (1.0e-6),
110 step_tolerance (1.0e-10),
111 log_stream (nullptr),
114 robust_estimate (false),
115 do_reorientation (false),
116 //CONF option: RegAnalyseDescent
117 //CONF default: 0 (false)
118 //CONF Linear registration: write comma separated gradient descent parameters and gradients
119 //CONF to stdout and verbose gradient descent output to stderr.
120 analyse_descent (File::Config::get_bool ("RegAnalyseDescent", false)) {
121 stages[0].scale_factor = 0.25;
122 stages[0].fod_lmax = 0;
123 stages[1].scale_factor = 0.5;
124 stages[1].fod_lmax = 2;
125 stages[2].scale_factor = 1.0;
126 stages[2].fod_lmax = 4;
127 }
128
129 // set_scale_factor needs to be the first option that is set as it overwrites the stage vector
130 void set_scale_factor (const vector<default_type>& scalefactor) {
131 stages.resize (scalefactor.size());
132 for (size_t level = 0; level < scalefactor.size(); ++level) {
133 if (scalefactor[level] <= 0 || scalefactor[level] > 1.0)
134 throw Exception ("the linear registration scale factor for each multi-resolution level must be between 0 and 1");
135 stages[level].scale_factor = scalefactor[level];
136 }
137 }
138
139 // needs to be set before set_stage_iterations is set
140 void set_stage_optimiser_default (const OptimiserAlgoType& type) {
141 for (auto & stage : stages)
142 stage.optimiser_default = type;
143 }
144
145 // needs to be set before set_stage_iterations is set
146 void set_stage_optimiser_first (const OptimiserAlgoType& type) {
147 for (auto & stage : stages)
148 stage.optimiser_first = type;
149 }
150
151 // needs to be set before set_stage_iterations is set
152 void set_stage_optimiser_last (const OptimiserAlgoType& type) {
153 for (auto & stage : stages)
154 stage.optimiser_last = type;
155 }
156
157 void set_stage_iterations (const vector<uint32_t>& it) {
158 for (size_t i = 0; i < it.size (); ++i)
159 if (!it[i])
160 throw Exception ("the number of stage iterations must be positive");
161 if (it.size() == stages.size()) {
162 for (size_t i = 0; i < stages.size (); ++i)
163 stages[i].stage_iterations = it[i];
164 } else if (it.size() == 1) {
165 for (size_t i = 0; i < stages.size (); ++i)
166 stages[i].stage_iterations = it[0];
167 } else
168 throw Exception ("the number of stage iterations must be defined for all stages (1 or " + str(stages.size())+")");
169 for (auto & stage : stages) {
170 stage.optimisers.resize(stage.stage_iterations, stage.optimiser_default);
171 stage.optimisers[0] = stage.optimiser_first;
172 if (stage.stage_iterations > 1)
173 stage.optimisers[stage.stage_iterations - 1] = stage.optimiser_last;
174 }
175 }
176
177 void set_max_iter (const vector<uint32_t>& maxiter) {
178 if (maxiter.size() == stages.size()) {
179 for (size_t i = 0; i < stages.size (); ++i)
180 stages[i].gd_max_iter = maxiter[i];
181 } else if (maxiter.size() == 1) {
182 for (size_t i = 0; i < stages.size (); ++i)
183 stages[i].gd_max_iter = maxiter[0];
184 } else
185 throw Exception ("the number of gradient descent iterations must be defined for all stages (1 or " + str(stages.size())+")");
186 }
187
188 // needs to be set before set_lmax
189 void set_directions (Eigen::MatrixXd& dir) {
190 aPSF_directions = dir;
191 do_reorientation = true;
192 }
193
194 void set_lmax (const vector<uint32_t>& lmax) {
195 for (size_t i = 0; i < lmax.size (); ++i)
196 if (lmax[i] % 2)
197 throw Exception ("the input lmax must be even");
198 if (lmax.size() == stages.size()) {
199 for (size_t i = 0; i < stages.size (); ++i)
200 stages[i].fod_lmax = lmax[i];
201 } else if (lmax.size() == 1) {
202 for (size_t i = 0; i < stages.size (); ++i)
203 stages[i].fod_lmax = lmax[0];
204 } else
205 throw Exception ("the lmax must be defined for all stages (1 or " + str(stages.size())+")");
206 }
207
208 // needs to be set after set_lmax
209 void set_mc_parameters (const vector<MultiContrastSetting>& mcs) {
210 contrasts = mcs;
211 }
212
213 void set_loop_density (const vector<default_type>& loop_density_){
214 for (size_t d = 0; d < loop_density_.size(); ++d)
215 if (loop_density_[d] < 0.0 or loop_density_[d] > 1.0 )
216 throw Exception ("loop density must be between 0.0 and 1.0");
217 if (loop_density_.size() == stages.size()) {
218 for (size_t i = 0; i < stages.size (); ++i)
219 stages[i].loop_density = loop_density_[i];
220 } else if (loop_density_.size() == 1) {
221 for (size_t i = 0; i < stages.size (); ++i)
222 stages[i].loop_density = loop_density_[0];
223 } else
224 throw Exception ("the lmax must be defined for all stages (1 or " + str(stages.size())+")");
225 }
226
227 void set_diagnostics_image_prefix (const std::basic_string<char>& diagnostics_image_prefix) {
228 for (size_t level = 0; level < stages.size(); ++level) {
229 auto & stage = stages[level];
230 for (size_t iter = 1; iter <= stage.stage_iterations; ++iter) {
231 std::ostringstream oss;
232 oss << diagnostics_image_prefix << "_stage-" << level + 1 << "_iter-" << iter << ".mif";
233 if (Path::exists(oss.str()) && !App::overwrite_files)
234 throw Exception ("diagnostics image file \"" + oss.str() + "\" already exists (use -force option to force overwrite)");
235 stage.diagnostics_images.push_back(oss.str());
236 }
237 }
238 }
239
240 void set_extent (const vector<size_t> extent) {
241 for (size_t d = 0; d < extent.size(); ++d) {
242 if (extent[d] < 1)
243 throw Exception ("the neighborhood kernel extent must be at least 1 voxel");
244 }
245 kernel_extent = extent;
246 }
247
248 void set_init_translation_type (Transform::Init::InitType type) {
250 }
251
252 void set_init_rotation_type (Transform::Init::InitType type) {
253 init_rotation_type = type;
254 }
255
256 void use_robust_estimate (bool use) {
257 robust_estimate = use;
258 }
259
260
261 void set_grad_tolerance (const float& tolerance) {
262 grad_tolerance = tolerance;
263 }
264
265 void set_log_stream (std::streambuf* stream) {
266 log_stream = stream;
267 }
268
269 ssize_t get_lmax () {
270 ssize_t lmax=0;
271 for (auto& s : stages)
272 lmax = std::max(s.fod_lmax, lmax);
273 return (int) lmax;
274 }
275
276 Header get_midway_header () {
278 }
279
280 template <class MetricType, class TransformType, class Im1ImageType, class Im2ImageType>
281 void run (
282 MetricType& metric,
283 TransformType& transform,
284 Im1ImageType& im1_image,
285 Im2ImageType& im2_image) {
286 using BogusMaskType = Image<float>;
287 run_masked<MetricType, TransformType, Im1ImageType, Im2ImageType, BogusMaskType, BogusMaskType >
288 (metric, transform, im1_image, im2_image, nullptr, nullptr);
289 }
290
291 template <class MetricType, class TransformType, class Im1ImageType, class Im2ImageType, class Im2MaskType>
292 void run_im2_mask (
293 MetricType& metric,
294 TransformType& transform,
295 Im1ImageType& im1_image,
296 Im2ImageType& im2_image,
297 std::unique_ptr<Im2MaskType>& im2_mask) {
298 using BogusMaskType = Image<float>;
299 run_masked<MetricType, TransformType, Im1ImageType, Im2ImageType, BogusMaskType, Im2MaskType >
300 (metric, transform, im1_image, im2_image, nullptr, im2_mask);
301 }
302
303
304 template <class MetricType, class TransformType, class Im1ImageType, class Im2ImageType, class Im1MaskType>
305 void run_im1_mask (
306 MetricType& metric,
307 TransformType& transform,
308 Im1ImageType& im1_image,
309 Im2ImageType& im2_image,
310 std::unique_ptr<Im1MaskType>& im1_mask) {
311 using BogusMaskType = Image<float>;
312 run_masked<MetricType, TransformType, Im1ImageType, Im2ImageType, Im1MaskType, BogusMaskType >
313 (metric, transform, im1_image, im2_image, im1_mask, nullptr);
314 }
315
316 template <class MetricType, class TransformType, class Im1ImageType, class Im2ImageType, class Im1MaskType, class Im2MaskType>
317 void run_masked (
318 MetricType& metric,
319 TransformType& transform,
320 Im1ImageType& im1_image,
321 Im2ImageType& im2_image,
322 Im1MaskType& im1_mask,
323 Im2MaskType& im2_mask) {
324
326 for (auto & s : stages)
327 if (s.fod_lmax < 0)
328 throw Exception ("the lmax needs to be defined for each registration stage");
329
331 Transform::Init::initialise_using_image_mass (im1_image, im2_image, im1_mask, im2_mask, transform, init, contrasts);
333 Transform::Init::initialise_using_image_centres (im1_image, im2_image, im1_mask, im2_mask, transform, init);
334 else if (init_translation_type == Transform::Init::set_centre_mass) // doesn't change translation or linear matrix
335 Transform::Init::set_centre_via_mass (im1_image, im2_image, im1_mask, im2_mask, transform, init, contrasts);
336 else if (init_translation_type == Transform::Init::set_centre_geometric) // doesn't change translation or linear matrix
337 Transform::Init::set_centre_via_image_centres (im1_image, im2_image, im1_mask, im2_mask, transform, init);
338
340 Transform::Init::initialise_using_image_moments (im1_image, im2_image, im1_mask, im2_mask, transform, init, contrasts);
342 Transform::Init::initialise_using_rotation_search (im1_image, im2_image, im1_mask, im2_mask, transform, init, contrasts);
343
344
345 INFO ("Transformation before registration:");
346 INFO (transform.info());
347
348 INFO ("Linear registration stage parameters:");
349 for (auto & stage : stages) {
350 INFO(stage.info());
351 }
352
353 // TODO global search
354 // if (global_search) {
355 // GlobalSearch::GlobalSearch transformation_search;
356 // if (log_stream) {
357 // transformation_search.set_log_stream(log_stream);
358 // }
359 // // std::ofstream outputFile( "/tmp/log.txt" );
360 // // transformation_search.set_log_stream(outputFile.rdbuf());
361 // // transformation_search.set_log_stream(std::cerr.rdbuf());
362 // transformation_search.run_masked (metric, transform, im1_image, im2_image, im1_mask, im2_mask, init);
363 // // transform.debug();
364 // }
365
366 using MidwayImageType = Header;
367 using ProcessedImageType = Im1ImageType;
368 using ProcessedMaskType = Image<bool>;
369
370#ifdef REGISTRATION_CUBIC_INTERP
371 // using Im1ImageInterpolatorType = Interp::SplineInterp<Im1ImageType, Math::UniformBSpline<typename Im1ImageType::value_type>, Math::SplineProcessingType::ValueAndDerivative>;
372 // using Im2ImageInterpolatorType = Interp::SplineInterp<Im2ImageType, Math::UniformBSpline<typename Im2ImageType::value_type>, Math::SplineProcessingType::ValueAndDerivative>;
373 // using ProcessedImageInterpolatorType = Interp::SplineInterp<ProcessedImageType, Math::UniformBSpline<typename ProcessedImageType::value_type>, Math::SplineProcessingType::ValueAndDerivative>;
374#else
378#endif
379
380 using ParamType = Metric::Params<TransformType,
381 Im1ImageType,
382 Im2ImageType,
383 MidwayImageType,
384 Im1MaskType,
385 Im2MaskType,
386 Im1ImageInterpolatorType,
387 Im2ImageInterpolatorType,
390 ProcessedImageType,
391 ProcessedImageInterpolatorType,
392 ProcessedMaskType,
394
395 Eigen::Matrix<typename TransformType::ParameterType, Eigen::Dynamic, 1> optimiser_weights = transform.get_optimiser_weights();
396
397 // calculate midway (affine average) space which will be constant for each resolution level
398 midway_image_header = compute_minimum_average_header (im1_image, im2_image, transform.get_transform_half_inverse(), transform.get_transform_half());
399
400 for (size_t istage = 0; istage < stages.size(); istage++) {
401 auto& stage = stages[istage];
402
403 CONSOLE ("linear stage " + str(istage + 1) + "/"+str(stages.size()) + ", " + stage.info(do_reorientation));
404 // define or adjust tissue contrast lmax, nvols for this stage
406 if (stage_contrasts.size()) {
407 for (auto & mc : stage_contrasts) {
408 mc.lower_lmax (stage.fod_lmax);
409 }
410 } else {
411 MultiContrastSetting mc (im1_image.ndim()<4? 1:im1_image.size(3), do_reorientation, stage.fod_lmax);
412 stage_contrasts.push_back(mc);
413 }
414
415 DEBUG ("before downsampling:");
416 for (const auto & mc : stage_contrasts)
417 DEBUG (str(mc));
418
419 INFO ("smoothing image 1");
420 auto im1_smoothed = Registration::multi_resolution_lmax (im1_image, stage.scale_factor, do_reorientation, stage_contrasts);
421 INFO ("smoothing image 2");
422 auto im2_smoothed = Registration::multi_resolution_lmax (im2_image, stage.scale_factor, do_reorientation, stage_contrasts, &stage_contrasts);
423
424 DEBUG ("after downsampling:");
425 for (const auto & mc : stage_contrasts)
426 INFO (str(mc));
427
428
429 Filter::Resize midway_resize_filter (midway_image_header);
430 midway_resize_filter.set_scale_factor (stage.scale_factor);
431 Header midway_resized (midway_resize_filter);
432
433 ParamType parameters (transform, im1_smoothed, im2_smoothed, midway_resized, im1_mask, im2_mask);
434 parameters.loop_density = stage.loop_density;
435 if (contrasts.size())
436 parameters.set_mc_settings (stage_contrasts);
437
438
439 // if (robust_estimate)
440 // INFO ("using robust estimate");
441 // parameters.robust_estimate = robust_estimate; // TODO
442
443 // set control point coordinates inside +-1/3 of the midway_image size
444 {
445 Eigen::Vector3d ext (midway_image_header.spacing(0) / 6.0,
446 midway_image_header.spacing(1) / 6.0,
447 midway_image_header.spacing(2) / 6.0);
448 for (size_t i = 0; i<3; ++i)
449 ext(i) *= midway_image_header.size(i) - 0.5;
450 parameters.set_control_points_extent(ext);
451 }
452 DEBUG ("neighbourhood kernel extent: " + str(kernel_extent));
453 parameters.set_extent (kernel_extent);
454 Eigen::Vector3d spacing (
455 midway_image_header.spacing(0),
456 midway_image_header.spacing(1),
457 midway_image_header.spacing(2));
458 Eigen::Vector3d coherence(spacing);
459 Eigen::Vector3d stop(spacing);
460 //CONF option: RegCoherenceLen
461 //CONF default: 3.0
462 //CONF Linear registration: estimated spatial coherence length in voxels.
463 default_type reg_coherence_len = File::Config::get_float ("RegCoherenceLen", 3.0); // = 3 stdev blur
464 coherence *= reg_coherence_len * 1.0 / (2.0 * stage.scale_factor);
465 //CONF option: RegStopLen
466 //CONF default: 0.0001
467 //CONF Linear registration: smallest gradient descent step measured in fraction of a voxel at which to stop registration.
468 default_type reg_stop_len = File::Config::get_float ("RegStopLen", 0.0001);
469 stop.array() *= reg_stop_len;
470 DEBUG ("coherence length: " + str(coherence));
471 DEBUG ("stop length: " + str(stop));
472 transform.get_gradient_descent_updator()->set_control_points (parameters.control_points, coherence, stop, spacing);
473
474 // convergence check using slope of smoothed parameter trajectories
475 Eigen::VectorXd slope_threshold = Eigen::VectorXd::Ones (12);
476 //CONF option: RegGdConvergenceThresh
477 //CONF default: 5e-3
478 //CONF Linear registration: threshold for convergence check using the smoothed control point trajectories
479 //CONF measured in fraction of a voxel.
480 slope_threshold.fill (spacing.mean() * File::Config::get_float ("RegGdConvergenceThresh", 5e-3f));
481 DEBUG ("convergence slope threshold: " + str(slope_threshold[0]));
482 //CONF option: RegGdConvergenceDataSmooth
483 //CONF default: 0.8
484 //CONF Linear registration: control point trajectory smoothing value used in convergence check
485 //CONF parameter range: [0...1].
486 const default_type alpha (MR::File::Config::get_float ("RegGdConvergenceDataSmooth", 0.8));
487 if ( (alpha < 0.0f ) || (alpha > 1.0f) )
488 throw Exception ("config file option RegGdConvergenceDataSmooth has to be in the range: [0...1]");
489 //CONF option: RegGdConvergenceSlopeSmooth
490 //CONF default: 0.1
491 //CONF Linear registration: control point trajectory slope smoothing value used in convergence check
492 //CONF parameter range: [0...1].
493 const default_type beta (MR::File::Config::get_float ("RegGdConvergenceSlopeSmooth", 0.1));
494 if ( (beta < 0.0f ) || (beta > 1.0f) )
495 throw Exception ("config file option RegGdConvergenceSlopeSmooth has to be in the range: [0...1]");
496 size_t buffer_len (MR::File::Config::get_float ("RegGdConvergenceBufferLen", 4));
497 //CONF option: RegGdConvergenceMinIter
498 //CONF default: 10
499 //CONF Linear registration: minimum number of iterations until convergence check is activated.
500 size_t min_iter (MR::File::Config::get_float ("RegGdConvergenceMinIter", 10));
501 transform.get_gradient_descent_updator()->set_convergence_check (slope_threshold, alpha, beta, buffer_len, min_iter);
502
503 Metric::Evaluate<MetricType, ParamType> evaluate (metric, parameters);
504 if (do_reorientation && stage.fod_lmax > 0)
505 evaluate.set_directions (aPSF_directions);
506
507 INFO ("registration stage running...");
508 for (auto stage_iter = 1U; stage_iter <= stage.stage_iterations; ++stage_iter) {
509 if (stage.gd_max_iter > 0 and stage.optimisers[stage_iter - 1] == OptimiserAlgoType::bbgd) {
510 Math::GradientDescentBB<Metric::Evaluate<MetricType, ParamType>, typename TransformType::UpdateType>
511 optim (evaluate, *transform.get_gradient_descent_updator());
512 optim.be_verbose (analyse_descent);
513 optim.precondition (optimiser_weights);
514 optim.run (stage.gd_max_iter, grad_tolerance, analyse_descent ? std::cout.rdbuf() : log_stream);
515 parameters.optimiser_update (optim, evaluate.overlap());
516 INFO (" iteration: "+str(stage_iter)+"/"+str(stage.stage_iterations)+" GD iterations: "+
517 str(optim.function_evaluations())+" cost: "+str(optim.value())+" overlap: "+str(evaluate.overlap()));
518 } else if (stage.gd_max_iter > 0) {
519 Math::GradientDescent<Metric::Evaluate<MetricType, ParamType>, typename TransformType::UpdateType>
520 optim (evaluate, *transform.get_gradient_descent_updator());
521 optim.be_verbose (analyse_descent);
522 optim.precondition (optimiser_weights);
523 optim.run (stage.gd_max_iter, grad_tolerance, analyse_descent ? std::cout.rdbuf() : log_stream);
524 parameters.optimiser_update (optim, evaluate.overlap());
525 INFO (" iteration: "+str(stage_iter)+"/"+str(stage.stage_iterations)+" GD iterations: "+
526 str(optim.function_evaluations())+" cost: "+str(optim.value())+" overlap: "+str(evaluate.overlap()));
527 }
528
529 if (log_stream) {
530 std::ostream log_os(log_stream);
531 log_os << "\n\n"; // two empty lines for gnuplot's index recognition
532 }
533 // debug cost function gradient
534 // auto params = optim.state();
535 // VAR(optim.function_evaluations());
536 // Math::check_function_gradient (evaluate, params, 0.0001, true, optimiser_weights);
537 if (stage.diagnostics_images.size()) {
538 CONSOLE(" creating diagnostics image: " + stage.diagnostics_images[stage_iter - 1]);
539 parameters.make_diagnostics_image (stage.diagnostics_images[stage_iter - 1], File::Config::get_bool ("RegLinregDiagnosticsImageMasked", false));
540 }
541 }
542 // update midway (affine average) space using the current transformations
543 midway_image_header = compute_minimum_average_header (im1_image, im2_image, parameters.transformation.get_transform_half_inverse(), parameters.transformation.get_transform_half());
544 }
545 INFO("linear registration done");
546 INFO (transform.info());
547 }
548
549 // template<class ImageType, class TransformType>
550 // void transform_image_midway (const ImageType& input, const TransformType& transformation,
551 // const bool do_reorientation, const bool input_is_one, const std::string& out_path, const Header& h_midway) {
552 // if (do_reorientation and aPSF_directions.size() == 0)
553 // throw Exception ("directions have to be calculated before reorientation");
554
555 // Image<typename ImageType::value_type> image_midway;
556 // Header midway_header (h_midway);
557 // midway_header.ndim() = input.ndim();
558 // for (size_t dim = 3; dim < input.ndim(); ++dim) {
559 // midway_header.spacing(dim) = input.spacing(dim);
560 // midway_header.size(dim) = input.size(dim);
561 // }
562 // image_midway = Image<typename ImageType::value_type>::create (out_path, midway_header).with_direct_io();
563 // if (input_is_one) {
564 // Filter::reslice<Interp::Cubic> (input, image_midway, transformation.get_transform_half(), Adapter::AutoOverSample, 0.0);
565 // if (do_reorientation)
566 // // 60 directions by default!
567 // Transform::reorient ("reorienting...", image_midway, image_midway, transformation.get_transform_half(), aPSF_directions);
568 // } else {
569 // Filter::reslice<Interp::Cubic> (input, image_midway, transformation.get_transform_half_inverse(), Adapter::AutoOverSample, 0.0);
570 // if (do_reorientation)
571 // // 60 directions by default!
572 // Transform::reorient ("reorienting...", image_midway, image_midway, transformation.get_transform_half_inverse(), aPSF_directions);
573 // }
574 // }
575
576 protected:
582 std::streambuf* log_stream;
586 Eigen::MatrixXd aPSF_directions;
587 const bool analyse_descent;
588
590 };
591
595 }
596}
597
598#endif
a class to hold a named list of Option's
static bool get_bool(const std::string &key, bool default_value)
static float get_float(const std::string &key, float default_value)
This class provides access to the voxel intensities of an Image, using nearest-neighbour interpolatio...
Definition: nearest.h:68
Computes the minimum of a function using a Barzilai Borwein gradient descent approach....
Computes the minimum of a function using a gradient descent approach.
default_type grad_tolerance
Definition: linear.h:580
Transform::Init::InitType init_translation_type
Definition: linear.h:583
Eigen::MatrixXd aPSF_directions
Definition: linear.h:586
vector< MultiContrastSetting > contrasts
Definition: linear.h:578
Header midway_image_header
Definition: linear.h:589
vector< StageSetting > stages
Definition: linear.h:577
const bool analyse_descent
Definition: linear.h:587
vector< MultiContrastSetting > stage_contrasts
Definition: linear.h:578
default_type step_tolerance
Definition: linear.h:581
Transform::Init::InitType init_rotation_type
Definition: linear.h:583
vector< size_t > kernel_extent
Definition: linear.h:579
std::streambuf * log_stream
Definition: linear.h:582
#define INFO(msg)
Definition: exception.h:74
#define DEBUG(msg)
Definition: exception.h:75
#define CONSOLE(msg)
Definition: exception.h:71
void init(int argc, const char *const *argv)
initialise MRtrix and parse command-line arguments
bool overwrite_files
vector< ParsedOption > option
the list of options parsed from the command-line
bool exists(const std::string &path)
Definition: path.h:88
void initialise_using_image_moments(Image< default_type > &im1, Image< default_type > &im2, Image< default_type > &mask1, Image< default_type > &mask2, Registration::Transform::Base &transform, Registration::Transform::Init::LinearInitialisationParams &init, const vector< MultiContrastSetting > &contrast_settings)
void initialise_using_rotation_search(Image< default_type > &im1, Image< default_type > &im2, Image< default_type > &mask1, Image< default_type > &mask2, Registration::Transform::Base &transform, Registration::Transform::Init::LinearInitialisationParams &init, const vector< MultiContrastSetting > &contrast_settings)
void initialise_using_image_mass(Image< default_type > &im1, Image< default_type > &im2, Image< default_type > &mask1, Image< default_type > &mask2, Registration::Transform::Base &transform, Registration::Transform::Init::LinearInitialisationParams &init, const vector< MultiContrastSetting > &contrast_settings)
void set_centre_via_image_centres(const Image< default_type > &im1, const Image< default_type > &im2, const Image< default_type > &mask1, const Image< default_type > &mask2, Registration::Transform::Base &transform, Registration::Transform::Init::LinearInitialisationParams &init)
void initialise_using_image_centres(const Image< default_type > &im1, const Image< default_type > &im2, const Image< default_type > &mask1, const Image< default_type > &mask2, Registration::Transform::Base &transform, Registration::Transform::Init::LinearInitialisationParams &init)
void set_centre_via_mass(Image< default_type > &im1, Image< default_type > &im2, Image< default_type > &mask1, Image< default_type > &mask2, Registration::Transform::Base &transform, Registration::Transform::Init::LinearInitialisationParams &init, const vector< MultiContrastSetting > &contrast_settings)
const App::OptionGroup rigid_options
const char * optim_algo_names[]
FORCE_INLINE ImageType multi_resolution_lmax(ImageType &input, const default_type scale_factor, const bool do_reorientation=false, const uint32_t lmax=0)
const App::OptionGroup adv_init_options
const App::OptionGroup lin_stage_options
void set_init_translation_model_from_option(Registration::Linear &registration, const int &option)
void parse_general_options(Registration::Linear &registration)
const App::OptionGroup affine_options
const App::OptionGroup fod_options
Definition: shared.h:35
void set_init_rotation_model_from_option(Registration::Linear &registration, const int &option)
LinearRobustMetricEstimatorType
Definition: linear.h:59
Definition: base.h:24
double default_type
the default type used throughout MRtrix
Definition: types.h:228
std::string str(const T &value, int precision=0)
Definition: mrtrix.h:247
Header compute_minimum_average_header(const vector< Header > &input_headers, const vector< Eigen::Transform< default_type, 3, Eigen::Projective > > &transform_header_with, int voxel_subsampling=1, Eigen::Matrix< default_type, 4, 1 > padding=Eigen::Matrix< default_type, 4, 1 >(1.0, 1.0, 1.0, 1.0))
#define MEMALIGN(...)
Definition: types.h:185
vector< OptimiserAlgoType > optimisers
Definition: linear.h:93
MEMALIGN(StageSetting) StageSetting()
Definition: linear.h:63
default_type loop_density
Definition: linear.h:95
std::string info(const bool &do_reorientation=true)
Definition: linear.h:75
OptimiserAlgoType optimiser_first
Definition: linear.h:94
OptimiserAlgoType optimiser_default
Definition: linear.h:94
vector< std::string > diagnostics_images
Definition: linear.h:97
OptimiserAlgoType optimiser_last
Definition: linear.h:94
default_type scale_factor
Definition: linear.h:92