Developer documentation
Version 3.0.3-105-gd3941f44
loop.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 __algo_loop_h__
18#define __algo_loop_h__
19
20#include "apply.h"
21#include "progressbar.h"
22#include "stride.h"
23#include "image_helpers.h"
24
25namespace MR
26{
27
29
30
31 namespace {
32
33 struct set_pos { NOMEMALIGN
34 FORCE_INLINE set_pos (size_t axis, ssize_t index) : axis (axis), index (index) { }
35 template <class ImageType>
36 FORCE_INLINE void operator() (ImageType& vox) { vox.index(axis) = index; }
37 size_t axis;
38 ssize_t index;
39 };
40
41 struct inc_pos { NOMEMALIGN
42 FORCE_INLINE inc_pos (size_t axis) : axis (axis) { }
43 template <class ImageType>
44 FORCE_INLINE void operator() (ImageType& vox) { ++vox.index(axis); }
45 size_t axis;
46 };
47
48 }
49
51
189 const size_t axis;
190
191 template <class... ImageType>
193 const size_t axis;
194 const std::tuple<ImageType&...> vox;
195 const ssize_t size0;
196 FORCE_INLINE Run (const size_t axis, const std::tuple<ImageType&...>& vox) :
197 axis (axis), vox (vox), size0 (std::get<0>(vox).size(axis)) { apply (set_pos (axis, 0), vox); }
198 FORCE_INLINE operator bool() const { return std::get<0>(vox).index(axis) < size0; }
199 FORCE_INLINE void operator++() const { apply (inc_pos (axis), vox); }
200 FORCE_INLINE void operator++(int) const { operator++(); }
201 };
202
203 template <class... ImageType>
204 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { axis, std::tie (images...) }; }
205 };
206
208 const std::string text;
209 const size_t axis;
210
211 template <class... ImageType>
214 const size_t axis;
215 const std::tuple<ImageType&...> vox;
216 const ssize_t size0;
217 FORCE_INLINE Run (const std::string& text, const size_t axis, const std::tuple<ImageType&...>& vox) :
218 progress (text, std::get<0>(vox).size(axis)), axis (axis), vox (vox), size0 (std::get<0>(vox).size(axis)) { apply (set_pos (axis, 0), vox); }
219 FORCE_INLINE operator bool() const { return std::get<0>(vox).index(axis) < size0; }
220 FORCE_INLINE void operator++() { apply (inc_pos (axis), vox); ++progress; }
222 };
223
224 template <class... ImageType>
225 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { text, axis, std::tie (images...) }; }
226 };
227
228
229
231 const size_t from, to;
232
233 template <class... ImageType>
235 const size_t from, to;
236 const std::tuple<ImageType&...> vox;
237 const ssize_t size0;
238 bool ok;
239 FORCE_INLINE Run (const size_t axis_from, const size_t axis_to, const std::tuple<ImageType&...>& vox) :
240 from (axis_from), to (axis_to ? axis_to : std::get<0>(vox).ndim()), vox (vox), size0 (std::get<0>(vox).size(from)), ok (true) {
241 for (size_t n = from; n < to; ++n)
242 apply (set_pos (n, 0), vox);
243 }
244 FORCE_INLINE operator bool() const { return ok; }
246 apply (inc_pos (from), vox);
247 if (std::get<0>(vox).index(from) < size0)
248 return;
249
250 apply (set_pos (from, 0), vox);
251 size_t axis = from+1;
252 while (axis < to) {
253 apply (inc_pos (axis), vox);
254 if (std::get<0>(vox).index(axis) < std::get<0>(vox).size(axis))
255 return;
256 apply (set_pos (axis, 0), vox);
257 ++axis;
258 }
259 ok = false;
260 }
262 };
263
264 template <class... ImageType>
265 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { from, to, std::tie (images...) }; }
266 };
267
269 const std::string text;
270 LoopAlongAxisRangeProgress (const std::string& text, const size_t from, const size_t to) :
271 LoopAlongAxisRange ({ from, to }), text (text) { }
272
273 template <class... ImageType>
274 struct Run : public LoopAlongAxisRange::Run<ImageType...> { NOMEMALIGN
276 FORCE_INLINE Run (const std::string& text, const size_t from, const size_t to, const std::tuple<ImageType&...>& vox) :
277 LoopAlongAxisRange::Run<ImageType...> (from, to, vox), progress (text, MR::voxel_count (std::get<0>(vox), from, to)) { }
280 };
281
282 template <class... ImageType>
283 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { text, from, to, std::tie (images...) }; }
284 };
285
286
287
289 template <class... ImageType>
290 FORCE_INLINE LoopAlongAxisRange::Run<ImageType...> operator() (ImageType&... images) const { return { 0, std::get<0>(std::tie(images...)).ndim(), std::tie (images...) }; }
291 };
292
294 const std::string text;
295 template <class... ImageType>
296 FORCE_INLINE LoopAlongAxisRangeProgress::Run<ImageType...> operator() (ImageType&... images) const { return { text, 0, std::get<0>(std::tie(images...)).ndim(), std::tie (images...) }; }
297 };
298
299
300
302 const std::initializer_list<size_t> axes;
303
304 template <class... ImageType>
306 const std::initializer_list<size_t> axes;
307 const std::tuple<ImageType&...> vox;
308 const size_t from;
309 const ssize_t size0;
310 bool ok;
311 FORCE_INLINE Run (const std::initializer_list<size_t> axes, const std::tuple<ImageType&...>& vox) :
312 axes (axes), vox (vox), from (*axes.begin()), size0 (std::get<0>(vox).size(from)), ok (true) {
313 for (auto axis : axes)
314 apply (set_pos (axis, 0), vox);
315 }
316 FORCE_INLINE operator bool() const { return ok; }
318 apply (inc_pos (from), vox);
319 if (std::get<0>(vox).index(from) < size0)
320 return;
321
322 apply (set_pos (from, 0), vox);
323 auto axis = axes.begin()+1;
324 while (axis != axes.end()) {
325 apply (inc_pos (*axis), vox);
326 if (std::get<0>(vox).index(*axis) < std::get<0>(vox).size(*axis))
327 return;
328 apply (set_pos (*axis, 0), vox);
329 ++axis;
330 }
331 ok = false;
332 }
334 };
335
336 template <class... ImageType>
337 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { axes, std::tie (images...) }; }
338 };
339
341 const std::string text;
342 LoopAlongStaticAxesProgress (const std::string& text, const std::initializer_list<size_t> axes) :
343 LoopAlongStaticAxes ({ axes }), text (text) { }
344
345 template <class... ImageType>
346 struct Run : public LoopAlongStaticAxes::Run<ImageType...> { NOMEMALIGN
348 FORCE_INLINE Run (const std::string& text, const std::initializer_list<size_t> axes, const std::tuple<ImageType&...>& vox) :
349 LoopAlongStaticAxes::Run<ImageType...> (axes, vox), progress (text, MR::voxel_count (std::get<0>(vox), axes)) { }
352 };
353
354 template <class... ImageType>
355 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { text, axes, std::tie (images...) }; }
356 };
357
358
359
362
363 template <class... ImageType>
366 const std::tuple<ImageType&...> vox;
367 const size_t from;
368 const ssize_t size0;
369 bool ok;
370 FORCE_INLINE Run (const vector<size_t>& axes, const std::tuple<ImageType&...>& vox) :
371 axes (axes), vox (vox), from (axes[0]), size0 (std::get<0>(vox).size(from)), ok (true) {
372 for (auto axis : axes)
373 apply (set_pos (axis, 0), vox);
374 }
375 FORCE_INLINE operator bool() const { return ok; }
377 apply (inc_pos (from), vox);
378 if (std::get<0>(vox).index(from) < size0)
379 return;
380
381 auto axis = axes.cbegin()+1;
382 while (axis != axes.cend()) {
383 apply (set_pos (*(axis-1), 0), vox);
384 apply (inc_pos (*axis), vox);
385 if (std::get<0>(vox).index(*axis) < std::get<0>(vox).size(*axis))
386 return;
387 ++axis;
388 }
389 ok = false;
390 }
392 };
393
394 template <class... ImageType>
395 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { axes, std::tie (images...) }; }
396 };
397
399 const std::string text;
402
403 template <class... ImageType>
404 struct Run : public LoopAlongDynamicAxes::Run<ImageType...> { NOMEMALIGN
406 FORCE_INLINE Run (const std::string& text, const vector<size_t>& axes, const std::tuple<ImageType&...>& vox) :
407 LoopAlongDynamicAxes::Run<ImageType...> (axes, vox), progress (text, MR::voxel_count (std::get<0>(vox), axes)) { }
410 };
411
412 template <class... ImageType>
413 FORCE_INLINE Run<ImageType...> operator() (ImageType&... images) const { return { text, axes, std::tie (images...) }; }
414 };
415
416
417
418 FORCE_INLINE LoopAlongAxes
420 { return { }; }
421
422 FORCE_INLINE LoopAlongAxesProgress
423 Loop (const std::string& progress_message)
424 { return { progress_message }; }
425
426 FORCE_INLINE LoopAlongSingleAxis
427 Loop (size_t axis)
428 { return { axis }; }
429
430 FORCE_INLINE LoopAlongSingleAxisProgress
431 Loop (const std::string& progress_message, size_t axis)
432 { return { progress_message, axis }; }
433
434 FORCE_INLINE LoopAlongAxisRange
435 Loop (size_t axis_from, size_t axis_to)
436 { return { axis_from, axis_to }; }
437
438 FORCE_INLINE LoopAlongAxisRangeProgress
439 Loop (const std::string& progress_message, size_t axis_from, size_t axis_to)
440 { return { progress_message, axis_from, axis_to }; }
441
442 FORCE_INLINE LoopAlongStaticAxes
443 Loop (std::initializer_list<size_t> axes)
444 { return { axes }; }
445
446 FORCE_INLINE LoopAlongStaticAxesProgress
447 Loop (const std::string& progress_message, std::initializer_list<size_t> axes)
448 { return { progress_message, axes }; }
449
450 FORCE_INLINE LoopAlongDynamicAxes
451 Loop (const vector<size_t>& axes)
452 { return { axes }; }
453
454 FORCE_INLINE LoopAlongDynamicAxesProgress
455 Loop (const std::string& progress_message, const vector<size_t>& axes)
456 { return { progress_message, axes }; }
457
458 template <class ImageType> FORCE_INLINE LoopAlongDynamicAxes
459 Loop (const ImageType& source,
460 size_t axis_from = 0,
461 size_t axis_to = std::numeric_limits<size_t>::max(),
462 typename std::enable_if<std::is_class<ImageType>::value && !std::is_same<ImageType, std::string>::value, int>::type = 0)
463 { return { Stride::order (source, axis_from, axis_to) }; }
464
465 template <class ImageType> FORCE_INLINE LoopAlongDynamicAxesProgress
466 Loop (const std::string& progress_message,
467 const ImageType& source,
468 size_t axis_from = 0,
469 size_t axis_to = std::numeric_limits<size_t>::max(),
470 typename std::enable_if<std::is_class<ImageType>::value && !std::is_same<ImageType, std::string>::value, int>::type = 0)
471 { return { progress_message, Stride::order (source, axis_from, axis_to) }; }
472
473
475}
476
477#endif
478
479
implements a progress meter to provide feedback to the user
Definition: progressbar.h:58
FORCE_INLINE LoopAlongAxes Loop()
Definition: loop.h:419
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
Definition: SH.h:233
#define NOMEMALIGN
Definition: memory.h:22
vector< size_t > order(const HeaderType &header, size_t from_axis=0, size_t to_axis=std::numeric_limits< size_t >::max())
sort range of axes with respect to their absolute stride.
Definition: stride.h:159
List get(const HeaderType &header)
return the strides of header as a vector<ssize_t>
Definition: stride.h:125
Definition: base.h:24
void apply(F &&f, T &&t)
invoke f(x) for each entry in t
Definition: apply.h:82
Definition: types.h:303
int axis
size_t index
#define FORCE_INLINE
Definition: types.h:156
NOMEMALIGN FORCE_INLINE LoopAlongAxisRange::Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:290
FORCE_INLINE LoopAlongAxisRangeProgress::Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:296
NOMEMALIGN const std::string text
Definition: loop.h:294
FORCE_INLINE void operator++()
Definition: loop.h:245
const std::tuple< ImageType &... > vox
Definition: loop.h:236
NOMEMALIGN const size_t from
Definition: loop.h:235
const ssize_t size0
Definition: loop.h:237
FORCE_INLINE void operator++(int)
Definition: loop.h:261
NOMEMALIGN const size_t to
Definition: loop.h:235
FORCE_INLINE Run(const size_t axis_from, const size_t axis_to, const std::tuple< ImageType &... > &vox)
Definition: loop.h:239
NOMEMALIGN const size_t to
Definition: loop.h:231
NOMEMALIGN const size_t from
Definition: loop.h:231
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:265
FORCE_INLINE void operator++()
Definition: loop.h:278
FORCE_INLINE void operator++(int)
Definition: loop.h:279
FORCE_INLINE Run(const std::string &text, const size_t from, const size_t to, const std::tuple< ImageType &... > &vox)
Definition: loop.h:276
NOMEMALIGN MR::ProgressBar progress
Definition: loop.h:275
LoopAlongAxisRangeProgress(const std::string &text, const size_t from, const size_t to)
Definition: loop.h:270
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:283
NOMEMALIGN const std::string text
Definition: loop.h:269
NOMEMALIGN const vector< size_t > axes
Definition: loop.h:365
FORCE_INLINE void operator++()
Definition: loop.h:376
FORCE_INLINE Run(const vector< size_t > &axes, const std::tuple< ImageType &... > &vox)
Definition: loop.h:370
const ssize_t size0
Definition: loop.h:368
FORCE_INLINE void operator++(int)
Definition: loop.h:391
const std::tuple< ImageType &... > vox
Definition: loop.h:366
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:395
NOMEMALIGN const vector< size_t > axes
Definition: loop.h:361
FORCE_INLINE void operator++()
Definition: loop.h:408
FORCE_INLINE void operator++(int)
Definition: loop.h:409
NOMEMALIGN MR::ProgressBar progress
Definition: loop.h:405
FORCE_INLINE Run(const std::string &text, const vector< size_t > &axes, const std::tuple< ImageType &... > &vox)
Definition: loop.h:406
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:413
NOMEMALIGN const std::string text
Definition: loop.h:399
LoopAlongDynamicAxesProgress(const std::string &text, const vector< size_t > &axes)
Definition: loop.h:400
const std::tuple< ImageType &... > vox
Definition: loop.h:194
const ssize_t size0
Definition: loop.h:195
FORCE_INLINE void operator++(int) const
Definition: loop.h:200
FORCE_INLINE void operator++() const
Definition: loop.h:199
FORCE_INLINE Run(const size_t axis, const std::tuple< ImageType &... > &vox)
Definition: loop.h:196
NOMEMALIGN const size_t axis
Definition: loop.h:193
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:204
NOMEMALIGN const size_t axis
Definition: loop.h:189
NOMEMALIGN MR::ProgressBar progress
Definition: loop.h:213
const std::tuple< ImageType &... > vox
Definition: loop.h:215
FORCE_INLINE void operator++()
Definition: loop.h:220
FORCE_INLINE Run(const std::string &text, const size_t axis, const std::tuple< ImageType &... > &vox)
Definition: loop.h:217
FORCE_INLINE void operator++(int)
Definition: loop.h:221
NOMEMALIGN const std::string text
Definition: loop.h:208
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:225
const std::tuple< ImageType &... > vox
Definition: loop.h:307
FORCE_INLINE void operator++(int)
Definition: loop.h:333
const ssize_t size0
Definition: loop.h:309
FORCE_INLINE void operator++()
Definition: loop.h:317
NOMEMALIGN const std::initializer_list< size_t > axes
Definition: loop.h:306
FORCE_INLINE Run(const std::initializer_list< size_t > axes, const std::tuple< ImageType &... > &vox)
Definition: loop.h:311
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:337
NOMEMALIGN const std::initializer_list< size_t > axes
Definition: loop.h:302
FORCE_INLINE void operator++()
Definition: loop.h:350
FORCE_INLINE Run(const std::string &text, const std::initializer_list< size_t > axes, const std::tuple< ImageType &... > &vox)
Definition: loop.h:348
FORCE_INLINE void operator++(int)
Definition: loop.h:351
NOMEMALIGN MR::ProgressBar progress
Definition: loop.h:347
FORCE_INLINE Run< ImageType... > operator()(ImageType &... images) const
Definition: loop.h:355
NOMEMALIGN const std::string text
Definition: loop.h:341
LoopAlongStaticAxesProgress(const std::string &text, const std::initializer_list< size_t > axes)
Definition: loop.h:342