Developer documentation
Version 3.0.3-105-gd3941f44
gradient_sort.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_sift_sort_h__
18#define __dwi_tractography_sift_sort_h__
19
20
21#include <set>
22
23#include "types.h"
24
27
28
29namespace MR
30{
31 namespace DWI
32 {
33 namespace Tractography
34 {
35 namespace SIFT
36 {
37
38
39
40
42 { MEMALIGN(Cost_fn_gradient_sort)
43 public:
44 Cost_fn_gradient_sort (const track_t i, const double g, const double gpul) :
45 tck_index (i),
46 cost_gradient (g),
47 grad_per_unit_length (gpul) { }
48
50 tck_index (that.tck_index),
51 cost_gradient (that.cost_gradient),
52 grad_per_unit_length (that.grad_per_unit_length) { }
53
54 void set (const track_t i, const double g, const double gpul) { tck_index = i; cost_gradient = g; grad_per_unit_length = gpul; }
55
56 bool operator< (const Cost_fn_gradient_sort& that) const { return grad_per_unit_length < that.grad_per_unit_length; }
57
58 track_t get_tck_index() const { return tck_index; }
59 double get_cost_gradient() const { return cost_gradient; }
60 double get_gradient_per_unit_length() const { return grad_per_unit_length; }
61
62 private:
63 track_t tck_index;
64 double cost_gradient;
65 double grad_per_unit_length;
66 };
67
68
69
70
71 // Sorting of the gradient vector in SIFT is done in a multi-threaded fashion, in a number of stages:
72 // * Gradient vector is split into blocks of equal size
73 // * Within each block:
74 // - Non-negative gradients are pushed to the end of the block (no need to sort these)
75 // - Negative gradients within the block are sorted fully
76 // - An iterator to the first entry in the sorted block is written to a set
77 // * For streamline filtering, the candidate streamline is chosen from the beginning of this set.
78 // The entry in the set corresponding to the gradient vector is removed, but the iterator WITHIN THE BLOCK
79 // is incremented and re-written to the set; this allows multiple streamlines from a single block to
80 // be filtered in a single iteration, provided the gradient is less than that of the candidate streamline
81 // from all other blocks
84
86 using VecItType = VecType::iterator;
87
88 class Comparator { NOMEMALIGN
89 public:
90 bool operator() (const VecItType& a, const VecItType& b) const { return (a->get_gradient_per_unit_length() < b->get_gradient_per_unit_length()); }
91 };
92 using SetType = std::set<VecItType, Comparator>;
93
94
95 public:
97
98 VecItType get();
99
100 bool operator() (const VecItType& in)
101 {
102 candidates.insert (in);
103 initial_candidates.insert (in);
104 return true;
105 }
106
107
108 private:
109 SetType candidates, initial_candidates;
110 VecItType end;
111
112
113 class BlockSender
114 { MEMALIGN(BlockSender)
115 public:
116 BlockSender (const track_t count, const track_t size) :
117 num_tracks (count),
118 block_size (size),
119 counter (0) { }
121 {
122 if (counter == num_tracks) {
123 out.first = out.second = 0;
124 return false;
125 }
126 out.first = counter;
127 counter = std::min (counter + block_size, num_tracks);
128 out.second = counter;
129 return true;
130 }
131 private:
132 const track_t num_tracks, block_size;
133 track_t counter;
134 };
135
136 class Sorter
137 { MEMALIGN(Sorter)
138 public:
139 Sorter (VecType& in) :
140 data (in) { }
141 Sorter (const Sorter& that) :
142 data (that.data) { }
143 bool operator() (const TrackIndexRange&, VecItType&) const;
144 private:
145 VecType& data;
146 };
147
148
149 };
150
151
152
153
154 }
155 }
156 }
157}
158
159
160#endif
161
162
#define NOMEMALIGN
Definition: memory.h:22
unsigned int track_t
Definition: types.h:34
std::pair< track_t, track_t > TrackIndexRange
Eigen::Matrix< default_type, 3, 1 > VecType
Definition: search.h:57
Definition: base.h:24
#define MEMALIGN(...)
Definition: types.h:185