cartodata  5.1.2
volumebase_d_inline.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef CARTODATA_VOLUME_VOLUMEBASE_D_INLINE_H
35 #define CARTODATA_VOLUME_VOLUMEBASE_D_INLINE_H
36 
37 //--- cartodata --------------------------------------------------------------
39 //--- cartobase --------------------------------------------------------------
41 //----------------------------------------------------------------------------
42 #include <iomanip>
43 
44 namespace carto {
45 
46  template < typename T >
47  inline
48  const T& Volume< T >::at( long x, long y, long z, long t ) const
49  {
50  /* using clang, blitz++ is about 2 times more efficient than our
51  implementation and achieves performances similar to pointer iterators.
52  Using gcc on the contrary it's our implementation which is about twice
53  faster.
54  */
55 # ifdef __clang__
56  return _blitz( blitz::TinyVector<long,4>( x, y, z, t ) );
57 # else
58  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& bstrides
59  = _blitz.stride();
60  return _items[ x * bstrides[0] + y * bstrides[1] + z * bstrides[2]
61  + t * bstrides[3] ];
62 # endif
63  }
64 
65 
66  template < typename T >
67  inline
68  const T& Volume< T >::operator()( long x, long y, long z, long t ) const
69  {
70  return at( x, y, z, t );
71  }
72 
73 
74  template < typename T >
75  inline
76  T& Volume< T >::at( long x, long y, long z, long t )
77  {
78  /* using clang, blitz++ is about 2 times more efficient than our
79  implementation and achieves performances similar to pointer iterators.
80  Using gcc on the contrary it's our implementation which is about twice
81  faster.
82  */
83 # ifdef __clang__
84  return _blitz( blitz::TinyVector<long,4>( x, y, z, t ) );
85 # else
86  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& bstrides
87  = _blitz.stride();
88 // std::cout << "carto::Volume<"
89 // << carto::DataTypeCode<Volume<T> >::dataType() << ">::at("
90 // << carto::toString(x) << ", "
91 // << carto::toString(y) << ", "
92 // << carto::toString(z) << ", "
93 // << carto::toString(t) << ")" << std::endl
94 // << "strides: [" << carto::toString(bstrides[0]) << ", "
95 // << carto::toString(bstrides[1]) << ", "
96 // << carto::toString(bstrides[2]) << ", "
97 // << carto::toString(bstrides[3]) << "] "
98 // << "offset:" << carto::toString(
99 // x * bstrides[0] + y * bstrides[1] + z * bstrides[2]
100 // + t * bstrides[3])
101 // << std::endl << std::flush;
102  return _items[ x * bstrides[0] + y * bstrides[1] + z * bstrides[2]
103  + t * bstrides[3] ];
104 # endif
105  }
106 
107 
108  template < typename T >
109  inline
110  T& Volume< T >::operator()( long x, long y, long z, long t )
111  {
112  return at( x, y, z, t );
113  }
114 
115 
116  template < typename T >
117  inline
118  const T& Volume< T >::at( const Position4Di & pos ) const
119  {
120  return at( pos[0], pos[1], pos[2], pos[3] );
121  }
122 
123 
124  template < typename T >
125  inline
126  const T& Volume< T >::operator()( const Position4Di & pos ) const
127  {
128  return at( pos );
129  }
130 
131 
132  template < typename T >
133  inline
134  T& Volume< T >::at( const Position4Di & pos )
135  {
136  return at( pos[0], pos[1], pos[2], pos[3] );
137  }
138 
139 
140  template < typename T >
141  inline
143  {
144  return at( pos );
145  }
146 
147 
148  template < typename T > inline
149  const T & Volume< T >::at( const std::vector<int> & index ) const
150  {
151  /* the blitz vector implementation with copy into a blitz TinyVector
152  seems always slower than direct use of index / strides
153  */
154 // blitz::TinyVector<int, Volume<T>::DIM_MAX> pos;
155 // int i, n = index.size();
156 // for( i=0; i<n && i<Volume<T>::DIM_MAX; ++i )
157 // pos[i] = index[i];
158 // for( ; i<Volume<T>::DIM_MAX; ++i )
159 // pos[i] = 0;
160 // return _blitz( pos );
161 
162 # if !defined( __clang__ ) && __GNUC__-0 < 5
163  /* the optimization of the accessor, and the best way to do it,
164  largely depends on the compiler (or processor ?)
165  For now it seems that for gcc 4.9 (on a i7 processor),
166  the best is this swich-based specialized cases. The for.. loop in this
167  situation is about 10 times slower.
168  For gcc 6 (on a i5), the compiler seems to optimize the for.. loop
169  better itself, and the swich slows the whole somewhat. But it is still
170  2 times slower than the (x, y, z, t) accessor, whereas it is only 30%
171  slower using gcc 4.
172  */
173  switch( index.size() )
174  {
175  case 1:
176  {
177  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
178  = _blitz.stride();
179 
180  return _blitz.dataZero()[ index[0] * strides[0] ];
181  }
182  case 2:
183  {
184  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
185  = _blitz.stride();
186 
187  return _blitz.dataZero()[ index[0] * strides[0]
188  + index[1] * strides[1] ];
189  }
190  case 3:
191  {
192  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
193  = _blitz.stride();
194 
195  return _blitz.dataZero()[ index[0] // * strides[0]
196  + index[1] * strides[1]
197  + index[2] * strides[2] ];
198  }
199  case 4:
200  {
201  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
202  = _blitz.stride();
203 
204  return _blitz.dataZero()[ index[0] * strides[0]
205  + index[1] * strides[1]
206  + index[2] * strides[2]
207  + index[3] * strides[3] ];
208  }
209  case 5:
210  {
211  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
212  = _blitz.stride();
213 
214  return _blitz.dataZero()[ index[0] * strides[0]
215  + index[1] * strides[1]
216  + index[2] * strides[2]
217  + index[3] * strides[3]
218  + index[4] * strides[4] ];
219  }
220  case 6:
221  {
222  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
223  = _blitz.stride();
224 
225  return _blitz.dataZero()[ index[0] * strides[0]
226  + index[1] * strides[1]
227  + index[2] * strides[2]
228  + index[3] * strides[3]
229  + index[4] * strides[4]
230  + index[5] * strides[5] ];
231  }
232  case 7:
233  {
234  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
235  = _blitz.stride();
236 
237  return _blitz.dataZero()[ index[0] * strides[0]
238  + index[1] * strides[1]
239  + index[2] * strides[2]
240  + index[3] * strides[3]
241  + index[4] * strides[4]
242  + index[5] * strides[5]
243  + index[6] * strides[6] ];
244  }
245  case 8:
246  {
247  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
248  = _blitz.stride();
249 
250  return _blitz.dataZero()[ index[0] * strides[0]
251  + index[1] * strides[1]
252  + index[2] * strides[2]
253  + index[3] * strides[3]
254  + index[4] * strides[4]
255  + index[5] * strides[5]
256  + index[6] * strides[6]
257  + index[7] * strides[7] ];
258  }
259  default:
260  {
261  /* using gcc 4.9 the blitz++ solution is 2 times faster than the
262  regular multiplication loop.
263  This is not the case using gcc 6.
264  */
265  blitz::TinyVector<int, Volume<T>::DIM_MAX> pos;
266  int i, n = index.size();
267  for( i=0; i<n && i<Volume<T>::DIM_MAX; ++i )
268  pos[i] = index[i];
269  for( ; i<Volume<T>::DIM_MAX; ++i )
270  pos[i] = 0;
271  return _blitz( pos );
272 
273 // const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
274 // = _blitz.stride();
275 // size_t offset = 0;
276 // for( int i=0; i!=index.size(); ++i )
277 // offset += index[i] * strides[i];
278 // return _blitz.dataZero()[ offset ];
279  }
280  }
281 
282  return *_blitz.dataZero();
283 
284 # else
285  /* using gcc 6 or clang, the blitz++ implementation seems less efficient
286  than a regular loop, and the loop is more efficient that the above
287  switch-case implementation.
288  */
289 
290  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
291  = _blitz.stride();
292 
293  size_t offset = 0;
294  for( int i=0; i!=index.size(); ++i )
295  offset += index[i] * strides[i];
296  return _blitz.dataZero()[ offset ];
297 # endif
298  }
299 
300  template < typename T > inline
301  T & Volume< T >::at( const std::vector<int> & index )
302  {
303  /* the blitz vector implementation with copy into a blitz TinyVector
304  seems always slower than direct use of index / strides
305  */
306 // blitz::TinyVector<int, Volume<T>::DIM_MAX> pos;
307 // int i, n = index.size();
308 // for( i=0; i<n && i<Volume<T>::DIM_MAX; ++i )
309 // pos[i] = index[i];
310 // for( ; i<Volume<T>::DIM_MAX; ++i )
311 // pos[i] = 0;
312 // return _blitz( pos );
313 
314 # if !defined( __clang__ ) && __GNUC__-0 < 5
315  /* the optimization of the accessor, and the best way to do it,
316  largely depends on the compiler (or processor ?)
317  For now it seems that for gcc 4.9 (on a i7 processor),
318  the best is this swich-based specialized cases. The for.. loop in this
319  situation is about 10 times slower.
320  For gcc 6 (on a i5), the compiler seems to optimize the for.. loop
321  better itself, and the swich slows the whole somewhat. But it is still
322  2 times slower than the (x, y, z, t) accessor, whereas it is only 30%
323  slower using gcc 4.
324  */
325  switch( index.size() )
326  {
327  case 1:
328  {
329  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
330  = _blitz.stride();
331 
332  return _blitz.dataZero()[ index[0] * strides[0] ];
333  }
334  case 2:
335  {
336  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
337  = _blitz.stride();
338 
339  return _blitz.dataZero()[ index[0] * strides[0]
340  + index[1] * strides[1] ];
341  }
342  case 3:
343  {
344  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
345  = _blitz.stride();
346 
347  return _blitz.dataZero()[ index[0] // * strides[0]
348  + index[1] * strides[1]
349  + index[2] * strides[2] ];
350  }
351  case 4:
352  {
353  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
354  = _blitz.stride();
355 
356  return _blitz.dataZero()[ index[0] * strides[0]
357  + index[1] * strides[1]
358  + index[2] * strides[2]
359  + index[3] * strides[3] ];
360  }
361  case 5:
362  {
363  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
364  = _blitz.stride();
365 
366  return _blitz.dataZero()[ index[0] * strides[0]
367  + index[1] * strides[1]
368  + index[2] * strides[2]
369  + index[3] * strides[3]
370  + index[4] * strides[4] ];
371  }
372  case 6:
373  {
374  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
375  = _blitz.stride();
376 
377  return _blitz.dataZero()[ index[0] * strides[0]
378  + index[1] * strides[1]
379  + index[2] * strides[2]
380  + index[3] * strides[3]
381  + index[4] * strides[4]
382  + index[5] * strides[5] ];
383  }
384  case 7:
385  {
386  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
387  = _blitz.stride();
388 
389  return _blitz.dataZero()[ index[0] * strides[0]
390  + index[1] * strides[1]
391  + index[2] * strides[2]
392  + index[3] * strides[3]
393  + index[4] * strides[4]
394  + index[5] * strides[5]
395  + index[6] * strides[6] ];
396  }
397  case 8:
398  {
399  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
400  = _blitz.stride();
401 
402  return _blitz.dataZero()[ index[0] * strides[0]
403  + index[1] * strides[1]
404  + index[2] * strides[2]
405  + index[3] * strides[3]
406  + index[4] * strides[4]
407  + index[5] * strides[5]
408  + index[6] * strides[6]
409  + index[7] * strides[7] ];
410  }
411  default:
412  {
413  /* using gcc 4.9 the blitz++ solution is 2 times faster than the
414  regular multiplication loop.
415  This is not the case using gcc 6.
416  */
417  blitz::TinyVector<int, Volume<T>::DIM_MAX> pos;
418  int i, n = index.size();
419  for( i=0; i<n && i<Volume<T>::DIM_MAX; ++i )
420  pos[i] = index[i];
421  for( ; i<Volume<T>::DIM_MAX; ++i )
422  pos[i] = 0;
423  return _blitz( pos );
424 
425 // const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
426 // = _blitz.stride();
427 // size_t offset = 0;
428 // for( int i=0; i!=index.size(); ++i )
429 // offset += index[i] * strides[i];
430 // return _blitz.dataZero()[ offset ];
431  }
432  }
433 
434  return *_blitz.dataZero();
435 
436 # else
437  /* using gcc 6 or clang, the blitz++ implementation seems less efficient
438  than a regular loop, and the loop is more efficient that the above
439  switch-case implementation.
440  */
441  const blitz::TinyVector<BlitzStridesType, Volume<T>::DIM_MAX>& strides
442  = _blitz.stride();
443 
444  size_t offset = 0;
445  for( int i=0; i!=index.size(); ++i )
446  offset += index[i] * strides[i];
447  return _blitz.dataZero()[ offset ];
448 # endif
449  }
450 
451  template < typename T > inline
452  const T& Volume< T >::operator() ( const std::vector<int> & position ) const
453  {
454  return at( position );
455  }
456 
457 
458  template < typename T > inline
459  T& Volume< T >::operator() ( const std::vector<int> & position )
460  {
461  return at( position );
462  }
463 
464  template < typename T > inline
465  const T & Volume< T >::at( const blitz::TinyVector<int,1> & index ) const
466  {
467  return _blitz( index );
468  }
469 
470  template < typename T > inline
471  T & Volume< T >::at( const blitz::TinyVector<int,1> & index )
472  {
473  return _blitz( index );
474  }
475 
476  template < typename T > inline
477  const T & Volume< T >::at( const blitz::TinyVector<int,2> & index ) const
478  {
479  return _blitz( index );
480  }
481 
482  template < typename T > inline
483  T & Volume< T >::at( const blitz::TinyVector<int,2> & index )
484  {
485  return _blitz( index );
486  }
487 
488  template < typename T > inline
489  const T & Volume< T >::at( const blitz::TinyVector<int,3> & index ) const
490  {
491  return _blitz( index );
492  }
493 
494  template < typename T > inline
495  T & Volume< T >::at( const blitz::TinyVector<int,3> & index )
496  {
497  return _blitz( index );
498  }
499 
500  template < typename T > inline
501  const T & Volume< T >::at( const blitz::TinyVector<int,4> & index ) const
502  {
503  return _blitz( index );
504  }
505 
506  template < typename T > inline
507  T & Volume< T >::at( const blitz::TinyVector<int,4> & index )
508  {
509  return _blitz( index );
510  }
511 
512  template < typename T > inline
513  const T & Volume< T >::at( const blitz::TinyVector<int,Volume<T>::DIM_MAX> & index ) const
514  {
515  return _blitz( index );
516  }
517 
518  template < typename T > inline
519  T & Volume< T >::at( const blitz::TinyVector<int,Volume<T>::DIM_MAX> & index )
520  {
521  return _blitz( index );
522  }
523 
524  template < typename T > inline
525  blitz::Array<T,Volume< T >::DIM_MAX>
526  Volume< T >::at( const blitz::RectDomain<Volume<T>::DIM_MAX> & subdomain ) const
527  {
528  return _blitz( subdomain );
529  }
530 
531  template < typename T > inline
532  blitz::Array<T,Volume< T >::DIM_MAX>
533  Volume< T >::at( const blitz::StridedDomain<Volume<T>::DIM_MAX> & subdomain ) const
534  {
535  return _blitz( subdomain );
536  }
537 
538  template < typename T > inline
539  blitz::Array<T,Volume< T >::DIM_MAX>
540  Volume< T >::at( const blitz::Range & r0 ) const
541  {
542  return _blitz( r0 );
543  }
544 
545  template < typename T > inline
546  blitz::Array<T,Volume< T >::DIM_MAX>
547  Volume< T >::at( const blitz::Range & r0, const blitz::Range & r1 ) const
548  {
549  return _blitz( r0, r1 );
550  }
551 
552  template < typename T > inline
553  blitz::Array<T,Volume< T >::DIM_MAX>
554  Volume< T >::at( const blitz::Range & r0, const blitz::Range & r1,
555  const blitz::Range & r2 ) const
556  {
557  return _blitz( r0, r1, r2 );
558  }
559 
560  template < typename T > inline
561  blitz::Array<T,Volume< T >::DIM_MAX>
562  Volume< T >::at( const blitz::Range & r0, const blitz::Range & r1,
563  const blitz::Range & r2, const blitz::Range & r3 ) const
564  {
565  return _blitz( r0, r1, r2, r3 );
566  }
567 
568  template < typename T >
569  inline
570  const T& Volume< T >::at( long x1, long x2, long x3, long x4, long x5,
571  long x6, long x7, long x8 ) const
572  {
573  return _blitz( blitz::TinyVector<long,8>( x1, x2, x3, x4, x5, x6, x7,
574  x8 ) );
575  }
576 
577  template < typename T >
578  inline
579  const T& Volume< T >::operator()( long x1, long x2, long x3, long x4,
580  long x5, long x6, long x7, long x8 ) const
581  {
582  return at( x1, x2, x3, x4, x5, x6, x7, x8 );
583  }
584 
585  template < typename T >
586  inline
587  T& Volume< T >::at( long x1, long x2, long x3, long x4,
588  long x5, long x6, long x7, long x8 )
589  {
590  return _blitz( blitz::TinyVector<long,8>( x1, x2, x3, x4, x5, x6, x7,
591  x8 ) );
592  }
593 
594 
595  template < typename T >
596  inline
597  T& Volume< T >::operator()( long x1, long x2, long x3, long x4,
598  long x5, long x6, long x7, long x8 )
599  {
600  return at( x1, x2, x3, x4, x5, x6, x7, x8 );
601  }
602 
603 
604  template <typename T>
606  {
607  return Object::reference( obj.header() );
608  }
609 
610  template <typename T>
611  inline
612  std::ostream & operator<< ( std::ostream & out,
613  const Volume<T> & volume )
614  {
615  VolumeOStream volumeout( out );
616  return volumeout << volume;
617  }
618 
619  template <typename T>
620  inline
621  std::ostream & operator<< ( const VolumeOStream & out,
622  const Volume<T> & volume )
623  {
624  out.ostream() << "Volume of " << DataTypeCode<T>::dataType() << ": ";
625  std::vector<int> dims = volume.getSize();
626  for( int d=0, n=dims.size(); d<n; ++d )
627  {
628  out.ostream() << dims[d];
629  if( d < n - 1 )
630  out.ostream() << " x ";
631  }
632  out.ostream() << std::endl;
633 
634  bool hasT = volume.getSizeT() > 1;
635  std::string tB = ( hasT ? "[" : "" );
636  std::string tE = ( hasT ? "]" : "" );
637  std::string tS = ( hasT ? " " : "" );
638  bool hasZ = volume.getSizeZ() > 1;
639  std::string zB = ( hasZ ? "[" : "" );
640  std::string zE = ( hasZ ? "]" : "" );
641  std::string zS = ( hasZ ? " " : "" );
642  bool hasY = volume.getSizeY() > 1;
643  std::string yB = ( hasY ? "[" : "" );
644  std::string yE = ( hasY ? "]" : "" );
645  std::string yS = ( hasY ? " " : "" );
646  bool hasX = volume.getSizeX() > 1;
647  std::string xB = ( hasX ? "[" : "" );
648  std::string xE = ( hasX ? "]" : "" );
649  std::string xS = ( hasX ? " " : "" );
650 
651  size_t sizeT = static_cast<size_t>(volume.getSizeT());
652  size_t sizeZ = static_cast<size_t>(volume.getSizeZ());
653  size_t sizeY = static_cast<size_t>(volume.getSizeY());
654  size_t sizeX = static_cast<size_t>(volume.getSizeX());
655 
656  for( size_t t = 0; t < sizeT; ++t )
657  {
658  if( hasT ) {
659  if( t < out.maxT() ) {
660  out.ostream() << std::setw(2) << std::left << tB;
661  } else {
662  out.ostream() << std::setw(3) << std::left << "...";
663  break;
664  }
665  }
666  for( size_t z = 0; z < sizeZ; ++z )
667  {
668  if( hasZ ) {
669  if( z < out.maxZ() ) {
670  out.ostream() << std::setw(2) << std::left << zB;
671  } else {
672  out.ostream() << std::setw(3) << std::left << "...";
673  break;
674  }
675  }
676  for( size_t y = 0; y < sizeY; ++y )
677  {
678  if( y < out.maxY() ) {
679  out.ostream() << std::setw(2) << std::left << yB;
680  } else {
681  out.ostream() << std::setw(3) << std::left << "...";
682  break;
683  }
684  for( size_t x = 0; x < sizeX; ++x )
685  {
686  if( x < out.maxX() ) {
687  out.ostream() << std::setw(10) << std::left
688  << toString( volume( x, y, z, t ) );
689  } else {
690  out.ostream() << std::setw(10) << std::left << "...";
691  break;
692  }
693  }
694  out.ostream() << std::setw(2) << std::left << yE;
695  if( y < sizeY - 1 )
696  out.ostream() << std::endl;
697  if( hasZ )
698  out.ostream() << std::setw(2) << std::left << zS;
699  if( hasT )
700  out.ostream() << std::setw(2) << std::left << tS;
701  }
702  if( hasZ )
703  out.ostream() << std::setw(2) << std::left << zE;
704  if( z < sizeZ - 1 )
705  out.ostream() << std::endl;
706  if( hasT )
707  out.ostream() << std::setw(2) << std::left << tS;
708  }
709  if( hasT )
710  out.ostream() << std::setw(2) << std::left << tE;
711  if( t < sizeT - 1 )
712  out.ostream() << std::endl;
713  }
714 
715  return out.ostream();
716  }
717 
718  template <typename T>
719  inline
721  int p = 0;
722  rc_ptr<Volume<T> > v(const_cast<Volume<T> *>(&vol));
723 
724  while (!v.isNull()) {
725  std::cout << "Volume " << (p ? carto::toString(p) + " " : "") << "is "
726  << (v->allocatorContext().isAllocated() ? "" : "not ")
727  << "allocated" << std::endl << std::flush;
728 
729  // Display volume dimensions
730  std::vector<int> dims = v->getSize();
731  if (dims.size()>0) {
732  std::cout << "Volume " << (p ? carto::toString(p) + " " : "")
733  << "dimensions [";
734  for(int i=0; i<dims.size()-1; ++i)
735  std::cout << dims[i] << ", ";
736  std::cout << dims[dims.size()-1] << "]" << std::endl << std::flush;
737  }
738 
739  // Display volume borders
740  std::vector<int> borders = v->getBorders();
741  std::cout << "Volume " << (p ? carto::toString(p) + " " : "")
742  << "borders [";
743  if (borders.size()>0) {
744  for(int i=0; i<borders.size()-1; ++i)
745  std::cout << borders[i] << ", ";
746  std::cout << borders[borders.size()-1] << "]" << std::endl << std::flush;
747  }
748 
749  // Display position in parent
750  typename Volume<T>::Position pos = v->posInRefVolume();
751  if (!v->refVolume().isNull()) {
752  std::vector<int> pos = v->posInRefVolume();
753  std::cout << "Volume " << (p ? carto::toString(p) + " " : "")
754  << "position in parent [";
755  for(int i=0; i<pos.size()-1; ++i)
756  std::cout << pos[i] << ", ";
757  std::cout << pos[pos.size()-1] << "]" << std::endl << std::flush;
758  }
759 
760  v = v->refVolume();
761  p++;
762  }
763  }
764 
765 } // namespace carto
766 
767 #endif // CARTODATA_VOLUME_VOLUMEBASE_D_INLINE_H
std::string dataType()
const PropertySet & header() const
Object reference(Object &value)
const size_t & maxT() const
const size_t & maxY() const
std::ostream & ostream() const
const size_t & maxZ() const
const size_t & maxX() const
int getSizeY() const
Definition: volumeproxy.h:99
int getSizeX() const
Definition: volumeproxy.h:89
std::vector< int > getSize() const
get the 4 dimensions in a vector
Definition: volumeproxy.h:129
int getSizeZ() const
Definition: volumeproxy.h:109
int getSizeT() const
Definition: volumeproxy.h:119
N-D Volume main class.
Definition: volumebase.h:119
std::vector< int > Position
Definition: volumebase.h:128
const T & at(long x, long y=0, long z=0, long t=0) const
const T & operator()(long x, long y=0, long z=0, long t=0) const
Warning: this operator is not virtual, so may not have the expected result on inherited classes (see ...
bool isNull() const
std::ostream & operator<<(std::ostream &out, const VoxelValue< T, C > &aa)
void displayRefVolumes(const Volume< T > &vol)
Display information about volumes hierarchy.
std::string toString(const T &object)
carto::Object getObjectHeader(Headered &h)