aimsdata 6.0.0
Neuroimaging data handling
borderiterator.h
Go to the documentation of this file.
1#ifndef AIMSDATA_BORDER_BORDERITERATOR_H
2#define AIMSDATA_BORDER_BORDERITERATOR_H
3
4
5#include <aims/vector/vector.h> // Point*
6#include <cartodata/volume/volume.h> // VolumeRef
7#include <iostream>
8
9namespace aims
10{
11 //==========================================================================
12 // BORDER ITERATOR
13 //==========================================================================
24 template <typename T>
26 {
27 public:
49 BorderIterator( carto::VolumeRef<T> in, bool inside = false,
50 const Point4dl & size = Point4dl( -1, -1, -1, -1 ) ):
51 _volume(in),
52 _inside(inside),
53 _sizeinf(size),
54 _sizesup(size)
55 {
56 if( !inside )
57 {
58 std::vector<int> borders = _volume.getBorders();
59 if( size[0] < 0 )
60 {
61 _sizeinf[0] = borders[0];
62 _sizesup[0] = borders[1];
63 }
64 if( size[1] < 0 )
65 {
66 _sizeinf[1] = borders[2];
67 _sizesup[1] = borders[3];
68 }
69 if( size[2] < 0 )
70 {
71 _sizeinf[2] = borders[4];
72 _sizesup[2] = borders[5];
73 }
74 if( size[3] < 0 )
75 {
76 _sizeinf[3] = borders[6];
77 _sizesup[3] = borders[7];
78 }
79 }
80 }
82 const Point4dl & sizeinf,
83 const Point4dl & sizesup ):
84 _volume(in),
85 _inside(inside),
86 _sizeinf(sizeinf),
87 _sizesup(sizesup)
88 {
89 if( !inside )
90 {
91 std::vector<int> borders = _volume.getBorders();
92 if( _sizeinf[0] < 0 )
93 _sizeinf[0] = borders[0];
94 if( _sizesup[0] < 0 )
95 _sizesup[0] = borders[1];
96
97 if( _sizeinf[1] < 0 )
98 _sizeinf[1] = borders[2];
99 if( _sizesup[1] < 0 )
100 _sizesup[1] = borders[3];
101
102 if( _sizeinf[2] < 0 )
103 _sizeinf[2] = borders[4];
104 if( _sizesup[1] < 0 )
105 _sizesup[2] = borders[5];
106
107 if( _sizeinf[3] < 0 )
108 _sizeinf[3] = borders[6];
109 if( _sizesup[1] < 0 )
110 _sizesup[3] = borders[7];
111 }
112 }
113
115 _volume( (carto::Volume<T>*)0 ),
116 _inside(false),
117 _sizeinf(),
118 _sizesup()
119 {}
120
121 public:
122 class iterator;
123
126 {
127 //--- constructors -----------------------------------------------------
128 public:
136 const_iterator( const iterator & other );
137 protected:
140 const_iterator( BorderIterator<T> & b, bool end = false );
142 const_iterator( BorderIterator<T> & b, const Point4dl & current );
143
144 //--- operators --------------------------------------------------------
145 public:
154 const T & operator*() const;
155 const T * operator->() const;
156 bool operator==( const const_iterator & other ) const;
157 bool operator==( const iterator & other ) const;
158 bool operator!=( const const_iterator & other ) const;
159 bool operator!=( const iterator & other ) const;
160
161 //--- member method ----------------------------------------------------
163 Point4dl coordinate() const { return _current; }
165 carto::VolumeRef<T> volume() { return _border._volume; }
166
167 //--- members ----------------------------------------------------------
168 protected:
171
172 //--- helpers ----------------------------------------------------------
173 protected:
175 bool isBorder( const Point4dl & p ) const;
177 bool isNonBorderImage( const Point4dl & p ) const;
180 Point4dl reset( const Point4dl & p,
181 const Point4dl & move ) const;
185 Point4dl nextMove( const Point4dl & move ) const;
191 Point4dl computeNext( const Point4dl & p ) const;
195 Point4dl end() const;
198 long jumpX() const;
199
200 //--- friends ----------------------------------------------------------
201 friend class BorderIterator<T>;
202 friend class iterator;
203 };
204
207 {
208 //--- constructors -----------------------------------------------------
209 public:
213 iterator();
215 iterator( const iterator & other );
216 protected:
219 iterator( BorderIterator<T> & b, bool end = false );
221 iterator( BorderIterator<T> & b, const Point4dl & current );
222
223 //--- operators --------------------------------------------------------
224 public:
226 iterator & operator=( const iterator & other );
229 iterator operator++(int);
230 T & operator*();
232
233 //--- friends ----------------------------------------------------------
234 friend class BorderIterator<T>;
235 };
236
237 public:
238 iterator begin() { return iterator(*this); }
239 iterator end() { return iterator(*this,true); }
240 const_iterator begin() const { return const_iterator(*this); }
241 const_iterator end() const { return const_iterator(*this,true); }
242
243 bool operator==( const BorderIterator<T> & other ) const
244 {
245 return ( _inside == other._inside ) &&
246 ( _sizeinf == other._sizeinf ) &&
247 ( _sizesup == other._sizesup ) &&
248 ( _volume.get()== other._volume.get() );
249 }
250
251 protected:
256
257 friend class const_iterator;
258 friend class iterator;
259 };
260
261 //--- const_iterator -------------------------------------------------------
262 template <typename T>
267
268 template <typename T>
270 _border(b),
271 _current( (end ? this->end() : Point4dl(0,0,0,0) ) )
272 {
273 if( !_border._inside && !end )
274 {
275 const Point4dl & start = _border._sizeinf;
276 _current = Point4dl( -start[0], -start[1], -start[2], -start[3] );
277 if( !isBorder(_current) )
278 _current = computeNext( _current );
279 }
280 }
281
282 template <typename T>
284 const Point4dl & current ):
285 _border(b),
286 _current(current)
287 {}
288
289 template <typename T>
291 const typename BorderIterator<T>::const_iterator & other ):
292 _border(other._border),
293 _current(other._current)
294 {}
295
296 template <typename T>
298 const typename BorderIterator<T>::iterator & other ):
299 _border(other._border),
300 _current(other._current)
301 {}
302
303 template <typename T>
305 const typename BorderIterator<T>::const_iterator & other )
306 {
307 _border = other._border;
308 _current = other._current;
309 return *this;
310 }
311
312 template <typename T>
314 const typename BorderIterator<T>::iterator & other )
315 {
316 _border = other._border;
317 _current = other._current;
318 return *this;
319 }
320
321 template <typename T>
323 {
324 return _border._volume( _current[0], _current[1], _current[2], _current[3] );
325 }
326
327 template <typename T>
329 {
330 return &( _border._volume( _current[0], _current[1], _current[2], _current[3] ) );
331 }
332
333 template <typename T>
335 {
336 return (_border == other._border) && (_current == other._current);
337 }
338
339 template <typename T>
341 {
342 return (_border == other._border) && (_current == other._current);
343 }
344
345 template <typename T>
347 {
348 return !(*this == other);
349 }
350
351 template <typename T>
353 {
354 return !(*this == other);
355 }
356
357 template <typename T>
365
366 template <typename T>
368 {
369 if( _border._inside )
370 return _border._volume.getSizeX() - _border._sizesup[0];
371 else
372 return _border._volume.getSizeX();
373 }
374
375 template <typename T>
377 {
378 if( _border._inside )
379 {
380 // outside allocated volume
381 if( ( p[0] < 0 ) || ( p[0] >= _border._volume.getSizeX() ) ||
382 ( p[1] < 0 ) || ( p[1] >= _border._volume.getSizeY() ) ||
383 ( p[2] < 0 ) || ( p[2] >= _border._volume.getSizeZ() ) ||
384 ( p[3] < 0 ) || ( p[3] >= _border._volume.getSizeT() ) )
385 return false;
386 // inside borders
387 else if( ( p[0] < _border._sizeinf[0] ) ||
388 ( p[0] >= _border._volume.getSizeX() - _border._sizesup[0] + 1 ) ||
389 ( p[1] < _border._sizeinf[1] ) ||
390 ( p[1] >= _border._volume.getSizeY() - _border._sizesup[1] + 1 ) ||
391 ( p[2] < _border._sizeinf[2] ) ||
392 ( p[2] >= _border._volume.getSizeZ() - _border._sizesup[2] + 1 ) ||
393 ( p[3] < _border._sizeinf[3] ) ||
394 ( p[3] >= _border._volume.getSizeT() - _border._sizesup[3] + 1 ) )
395 return true;
396 // inside non-border volume
397 else
398 return false;
399 }
400 else
401 {
402 // outside allocated volume
403 if( ( p[0] < -_border._sizeinf[0] ) ||
404 ( p[0] >= _border._volume.getSizeX() + _border._sizesup[0] ) ||
405 ( p[1] < -_border._sizeinf[1] ) ||
406 ( p[1] >= _border._volume.getSizeY() + _border._sizesup[1] ) ||
407 ( p[2] < -_border._sizeinf[2] ) ||
408 ( p[2] >= _border._volume.getSizeZ() + _border._sizesup[2] ) ||
409 ( p[3] < -_border._sizeinf[3] ) ||
410 ( p[3] >= _border._volume.getSizeT() + _border._sizesup[3] ) )
411 return false;
412 // inside border
413 else if( ( p[0] < 0 ) || ( p[0] >= _border._volume.getSizeX() ) ||
414 ( p[1] < 0 ) || ( p[1] >= _border._volume.getSizeY() ) ||
415 ( p[2] < 0 ) || ( p[2] >= _border._volume.getSizeZ() ) ||
416 ( p[3] < 0 ) || ( p[3] >= _border._volume.getSizeT() ) )
417 return true;
418 // inside non-border volume
419 else
420 return false;
421 }
422 }
423
424 template <typename T>
426 {
427 if( _border._inside )
428 {
429 return( _border._sizeinf[0] <= p[0] && p[0] < _border._volume.getSizeX() - _border._sizesup[0] &&
430 _border._sizeinf[1] <= p[1] && p[1] < _border._volume.getSizeY() - _border._sizesup[1] &&
431 _border._sizeinf[2] <= p[2] && p[2] < _border._volume.getSizeZ() - _border._sizesup[2] &&
432 _border._sizeinf[3] <= p[3] && p[3] < _border._volume.getSizeT() - _border._sizesup[3] );
433 }
434 else
435 {
436 return( 0 <= p[0] && p[0] < _border._volume.getSizeX() &&
437 0 <= p[1] && p[1] < _border._volume.getSizeY() &&
438 0 <= p[2] && p[2] < _border._volume.getSizeZ() &&
439 0 <= p[3] && p[3] < _border._volume.getSizeT() );
440 }
441 }
442
443 template <typename T>
445 const Point4dl & p, const Point4dl & move ) const
446 {
447 Point4dl newp = p;
448
449 if( _border._inside )
450 {
451 if( move[0] > 0 )
452 newp[0] = 0;
453 else if( move[1] > 0 )
454 newp[1] = 0;
455 else if( move[2] > 0 )
456 newp[2] = 0;
457 else if( move[3] > 0 )
458 newp[3] = 0;
459 }
460 else
461 {
462 if( move[0] > 0 )
463 newp[0] = -_border._sizeinf[0];
464 else if( move[1] > 0 )
465 newp[1] = -_border._sizeinf[1];
466 else if( move[2] > 0 )
467 newp[2] = -_border._sizeinf[2];
468 else if( move[3] > 0 )
469 newp[3] = -_border._sizeinf[3];
470 }
471
472 return newp;
473 }
474
475 template <typename T>
477 const Point4dl & move ) const
478 {
479 if( move[0] > 0 )
480 return Point4dl(0,1,0,0);
481 else if( move[1] > 0 )
482 return Point4dl(0,0,1,0);
483 else if( move[2] > 0 )
484 return Point4dl(0,0,0,1);
485 else if( move[3] > 0 )
486 return Point4dl(0,0,0,0);
487
488 // error
489 return move;
490 }
491
492 template <typename T>
494 const Point4dl & current ) const
495 {
496 Point4dl move( 1, 0, 0, 0 );
497 Point4dl next = current + move;
498 while( !isBorder(next) && next != end() )
499 {
500 // if next is inside: jump inside image
501 if( isNonBorderImage( next ) ) {
502 next[0] = jumpX();
503 move = Point4dl( 1, 0, 0, 0 );
504 }
505 // else: reset studied dim at line begin, and change dim
506 else
507 {
508 next = reset( next, move );
509 move = nextMove( move );
510 if( move == Point4dl(0, 0, 0, 0) )
511 next = end();
512 else
513 next = next + move;
514 }
515 }
516
517 return next;
518 }
519
520 template <typename T>
526
527 template <typename T>
534
535 //--- iterator -------------------------------------------------------------
536 template <typename T>
540
541 template <typename T>
545
546 template <typename T>
550
551 template <typename T>
553 const typename BorderIterator<T>::iterator & other ):
554 const_iterator(other)
555 {}
556
557 template <typename T>
559 const typename BorderIterator<T>::iterator & other )
560 {
562 return *this;
563 }
564
565 template <typename T>
574
575 template <typename T>
584
585 template <typename T>
592
593 template <typename T>
601
602} // namespace aims
603
604#endif // AIMSDATA_BORDER_BORDERITERATOR_H
bool isBorder(const Point4dl &p) const
returns true if the p is in the border described by _border
const_iterator(const const_iterator &other)
Copy constructor from a const_iterator.
Point4dl coordinate() const
Returns the coordinates of the current point in the linked volume.
const_iterator & operator=(const iterator &other)
assignment from iterator
bool isNonBorderImage(const Point4dl &p) const
returns true if p is in the image but not in the border.
bool operator!=(const const_iterator &other) const
Point4dl reset(const Point4dl &p, const Point4dl &move) const
Sets the coordinate (in the dimension described by move) at its most inferior (i.e.
bool operator==(const const_iterator &other) const
const_iterator()
Default constructor Create a non initialized iterator than cannot be incremented or accessed.
const_iterator(const iterator &other)
Copy constructor from an iterator.
long jumpX() const
Gives the size of the non-border volume in the X dimension.
Point4dl nextMove(const Point4dl &move) const
Computes the next move.
const_iterator & operator++()
increment (prefix)
Point4dl computeNext(const Point4dl &p) const
computeNext(p) returns the next point in the border.
const_iterator & operator=(const const_iterator &other)
assignment from const_iterator
carto::VolumeRef< T > volume()
Returns a reference to the linked volume.
Point4dl end() const
Point value for the "end" iterator (which points to no voxel).
iterator(const iterator &other)
Copy constructor from an iterator.
iterator()
Default constructor Create a non initialized iterator than cannot be incremented or accessed.
iterator & operator++()
increment (prefix)
iterator & operator=(const iterator &other)
assignment from iterator
bool operator==(const BorderIterator< T > &other) const
const_iterator end() const
carto::VolumeRef< T > _volume
BorderIterator(carto::VolumeRef< T > in, bool inside, const Point4dl &sizeinf, const Point4dl &sizesup)
friend class const_iterator
const_iterator begin() const
BorderIterator(carto::VolumeRef< T > in, bool inside=false, const Point4dl &size=Point4dl(-1, -1, -1, -1))
Border constructor.
T * get() const
The class for EcatSino data write operation.
static _Tp max()
AimsVector< int64_t, 4 > Point4dl