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