cartodata 6.0.0
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 --------------------------------------------------------------
40#include <cartobase/object/object.h>
41//----------------------------------------------------------------------------
42#include <iomanip>
43
44namespace 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 _start[ 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 _start[ 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();
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
300 template < typename T > inline
301 T & Volume< T >::at( const std::vector<int> & index )
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();
332 return _blitz.dataZero()[ index[0] * strides[0] ];
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( size_t 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 }
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
766 template <typename T>
768 {
769 return _referential;
770 }
771
772
773 template <typename T>
778
779} // namespace carto
780
781#endif // CARTODATA_VOLUME_VOLUMEBASE_D_INLINE_H
std::string dataType()
const PropertySet & header() const
Object reference(Object &value)
Referential holds information about coordinates system and axes.
Definition referential.h:78
const size_t & maxZ() const
const size_t & maxY() const
std::ostream & ostream() const
const size_t & maxT() const
const size_t & maxX() const
int getSizeY() const
int getSizeX() const
Definition volumeproxy.h:91
std::vector< int > getSize() const
get the 4 dimensions in a vector
int getSizeZ() const
int getSizeT() const
N-D Volume main class.
Definition volumebase.h:120
std::vector< int > Position
Definition volumebase.h:130
const Referential & referential() const
Referential and orientation information.
Referential _referential
Definition volumebase.h:586
const T & at(long x, long y=0, long z=0, long t=0) const
blitz::Array< T, Volume< T >::DIM_MAX > _blitz
Definition volumebase.h:583
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
void displayRefVolumes(const Volume< T > &vol)
Display information about volumes hierarchy.
std::string toString(const T &object)
carto::Object getObjectHeader(Headered &h)
std::ostream & operator<<(std::ostream &out, const VoxelValue< T, C > &aa)