aimsdata 6.0.0
Neuroimaging data handling
cartodatavolume.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 AIMS_DATA_CARTODATAVOLUME_H
35#define AIMS_DATA_CARTODATAVOLUME_H
36
37#include <cartodata/volume/volume.h>
38#include <cartodata/volume/volumeoperators.h>
39#include <aims/vector/vector.h>
40#include <aims/rgb/rgb.h>
41#include <cartobase/smart/rcptr.h>
43#include <aims/data/pheader.h>
44
45#include <algorithm>
46
47/* Warn about obsolete header/class
48
49 The warning as a class attribute is too aggressive, it warns _each_ use of
50 the AimsData classes, and this happens at many many many places, which
51 results in typically dozens of thousands of stderr output from the compiler
52 for a single include.
53*/
54#ifndef AIMSDATA_CLASS_NO_DEPREC_WARNING
55#warning "<aims/data/data.h> and the AimsData<T> classes are obsolete, use carto::VolumeRef() instead"
56#endif
57
68template<typename T>
69class
70// #ifndef AIMSDATA_CLASS_NO_DEPREC_WARNING
71// __attribute__((__deprecated__("use carto::VolumeRef() instead")))
72// #endif
74{
75
76public:
77 typedef T value_type;
79 typedef T* pointer;
81 typedef T**** pointer4d;
83 typedef T* iterator;
85 typedef const T* const_iterator;
87 typedef T& reference;
89 typedef const T& const_reference;
91 typedef size_t size_type;
93 typedef ptrdiff_t difference_type;
94
99 bool empty() const;
100
101 AimsData( int dimx = 1, int dimy = 1, int dimz = 1, int dimt = 1,
102 int borderw = 0 );
103 AimsData( int dimx, int dimy, int dimz, int dimt,
104 int borderw, const carto::AllocatorContext & al );
105 AimsData( const AimsData<T>& other );
106 AimsData( const AimsData<T>& other, int borderw );
107 virtual ~AimsData();
108
109 // conversions with carto::Volume
112 AimsData<T> & operator = (
113 const carto::rc_ptr<carto::Volume<T> > & vol );
114
115 AimsData<T> & operator = ( const AimsData<T> & );
116 AimsData<T> & operator = ( const T & );
117
122 operator const carto::rc_ptr<carto::Volume<T> > & () const;
123 operator carto::VolumeRef<T> & ();
124 operator const carto::VolumeRef<T> & () const;
125
126 const carto::AllocatorContext & allocator() const;
127 int dimX() const;
128 int dimY() const;
129 int dimZ() const;
130 int dimT() const;
131 float sizeX() const;
132 float sizeY() const;
133 float sizeZ() const;
134 float sizeT() const;
135 void setSizeX( float sizex );
136 void setSizeY( float sizey );
137 void setSizeZ( float sizez );
138 void setSizeT( float sizet );
139 void setSizeXYZT( float sizex = 1.0f, float sizey = 1.0f,
140 float sizez = 1.0f, float sizet = 1.0f );
141 void setSizeXYZT( const AimsData<T>& other );
142 const aims::Header* header() const;
145 reference operator [] ( size_type n );
146 const_reference operator [] ( size_type n ) const;
147 reference operator () ( size_type x = 0, size_type y = 0,
148 size_type z = 0, size_type t = 0 );
149 const_reference operator () ( size_type x = 0, size_type y = 0,
150 size_type z = 0, size_type t = 0 ) const;
151 reference operator () ( const Point4d& pt );
152 const_reference operator () ( const Point4d& pt ) const;
153 reference operator () ( const Point4dl& pt );
154 const_reference operator () ( const Point4dl& pt ) const;
155 reference operator () ( const Point3d& pt );
156 const_reference operator () ( const Point3d& pt ) const;
157 reference operator () ( const Point3dl& pt );
158 const_reference operator () ( const Point3dl& pt ) const;
159 reference operator () ( const Point2d& pt );
160 const_reference operator () ( const Point2d& pt ) const;
161 reference operator () ( const Point2dl& pt );
162 const_reference operator () ( const Point2dl& pt ) const;
163
164 T minimum() const;
165 T maximum() const;
166 T minIndex( int* x, int* y, int* z, int* t ) const;
167 T maxIndex( int* x, int* y, int* z, int* t ) const;
168 void fillBorder( const T& val );
172
173 // functions from former Border API
174
176 int borderWidth() const;
178 int oFirstPoint() const;
180 int oLine() const;
182 int oPointBetweenLine() const;
184 int oSlice() const;
186 int oLineBetweenSlice() const;
188 int oVolume() const;
192 const std::vector<int> & borders() const;
193
194 private:
195 struct Private;
196
197 carto::VolumeRef<T> _volume;
198 Private *d;
199};
200
201
202#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
203
204namespace carto
205{
206
207 template<class T> class DataTypeCode<AimsData<T> >
208 {
209 public:
210 static std::string objectType()
211 { return "Volume"; }
212 static std::string dataType()
213 { return DataTypeCode<T>::dataType(); }
214 static std::string name()
215 {
216 return std::string("volume of ") + DataTypeCode< T >::name();
217 }
218 };
219
220 template <typename T>
225
226}
227
228#endif // DOXYGEN_HIDE_INTERNAL_CLASSES
229
230// private struct
231
232template<typename T>
234{
237
239
241};
242
243
244// inline methods definition
245
246// Private struct methods
247
248template<typename T>
249inline
254
255
256template<typename T>
257inline
259{
260 if( header )
261 delete header;
262}
263
264
265template<typename T>
266inline
268{
269 if( !vol->refVolume().isNull() ) // is a view to another volume
270 if (vol->refVolume()->allocatorContext().isAllocated()) {
271 // AimsData is not able to deal with different border sizes, so we get the
272 // minimum border through dimensions
273 const std::vector<int> vborders = vol->getBorders();
274
275 // Borders are not defined for T dimension so we must only deal with
276 // X, Y and Z dimensions
277 std::vector<int>::const_iterator vbordersend = (vborders.size() > 6
278 ? vborders.begin() + 6
279 : vborders.end());
280 if(vborders.begin() != vbordersend) {
281 std::vector<int>::const_iterator minit = std::min_element(vborders.begin(),
282 vbordersend);
283 return (minit == vbordersend ? 0 : *minit);
284 }
285 }
286 return 0;
287}
288
289
290// AimsData methods
291
292template <typename T>
294{
295 return _volume;
296}
297
298
299template <typename T>
301{
302 return _volume;
303}
304
305
306template <typename T>
308{
309 return _volume;
310}
311
312
313template <typename T>
315{
316 return _volume;
317}
318
319
320template<typename T>
321inline
323{
324 return &*_volume->begin();
325}
326
327
328template<typename T>
329inline
331{
332 return &*_volume->begin();
333}
334
335
336template<typename T>
337inline
339{
340 // &*_volume->end() may return 0 with some versions of blitz++
341 // do does not make a valid pointer for end
342 return &_volume->at( _volume->getSizeX() - 1, _volume->getSizeY() - 1,
343 _volume->getSizeZ() - 1, _volume->getSizeT() - 1 ) + 1;
344}
345
346
347template<typename T>
348inline
350{
351 // &*_volume->end() may return 0 with some versions of blitz++
352 // do does not make a valid pointer for end
353 return &_volume->at( _volume->getSizeX() - 1, _volume->getSizeY() - 1,
354 _volume->getSizeZ() - 1, _volume->getSizeT() - 1 ) + 1;
355}
356
357
358template<typename T>
359inline
361{
362 return _volume->begin() == _volume->end();
363}
364
365template<typename T>
366inline
367AimsData<T>::AimsData( int dimx, int dimy, int dimz, int dimt, int borderw )
368 : carto::RCObject(),
369 _volume( new carto::Volume<T>( dimx + borderw * 2, dimy + borderw * 2,
370 dimz + borderw * 2, dimt ) ),
371 d( new Private )
372{
373 if( borderw != 0 )
374 _volume.reset( new carto::Volume<T>(
375 _volume,
376 typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
377 typename carto::Volume<T>::Position4Di( dimx, dimy, dimz, dimt ) ) );
378 d->header = new aims::PythonHeader( *_volume );
379}
380
381
382template < typename T >
383inline
384AimsData<T>::AimsData( int dimx, int dimy, int dimz, int dimt,
385 int borderw, const carto::AllocatorContext & al )
386 : carto::RCObject(),
387 _volume( new carto::Volume<T>( dimx + borderw * 2, dimy + borderw * 2,
388 dimz + borderw * 2, dimt, al ) ),
389 d( new Private )
390{
391 if( borderw != 0 )
392 _volume.reset( new carto::Volume<T>(
393 _volume,
394 typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
395 typename carto::Volume<T>::Position4Di( dimx, dimy, dimz, dimt ), al ) );
396 d->header = new aims::PythonHeader( *_volume );
397}
398
399
400template < typename T >
401inline
403 : carto::RCObject(),
404 _volume( other._volume ),
405 d( new Private )
406{
407 d->header = new aims::PythonHeader( *_volume );
408}
409
410
411template < typename T >
412inline
413AimsData<T>::AimsData( const AimsData<T>& other, int borderw )
414 : carto::RCObject(),
415 _volume( new carto::Volume<T>( other.dimX() + borderw * 2,
416 other.dimY() + borderw * 2, other.dimZ() + borderw * 2, other.dimT() ) ),
417 d( new Private )
418{
419 _volume->copyHeaderFrom( other.volume()->header() );
420
421 if( borderw != 0 )
422 _volume.reset( new carto::Volume<T>(
423 _volume,
424 typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
425 typename carto::Volume<T>::Position4Di( other.dimX(), other.dimY(),
426 other.dimZ(), other.dimT() ) ) );
427
428 long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
429 for ( t = 0; t < tm; t++ )
430 for ( z = 0; z < zm; z++ )
431 for ( y = 0; y < ym; y++ )
432 for ( x = 0; x < xm; x++ )
433 (*this)( x, y, z, t ) = other( x, y, z, t );
434 d->header = new aims::PythonHeader( *_volume );
435}
436
437
438template < typename T >
439inline
441{
442 delete d;
443}
444
445
446template < typename T >
447inline
449 : carto::RCObject(),
450 _volume( vol ),
451 d( new Private )
452{
453 d->header = new aims::PythonHeader( *_volume );
454}
455
456template < typename T >
457inline
459 : carto::RCObject(),
460 _volume( vol ),
461 d( new Private )
462{
463 d->header = new aims::PythonHeader( *_volume );
464}
465
466
467template < typename T >
468inline
470 const carto::rc_ptr<carto::Volume<T> > & vol )
471{
472 if( _volume.get() == vol.get() )
473 return *this;
474
475 delete d->header;
476 _volume = vol;
477 d->header = new aims::PythonHeader( *_volume );
478
479 return *this;
480}
481
482
483template < typename T >
484inline
486{
487 if ( &other == this )
488 return *this;
489
490 delete d->header;
491 _volume = other._volume;
492 *d = *other.d;
493 d->header = new aims::PythonHeader( *_volume );
494
495 return *this;
496}
497
498
499template < typename T >
500inline
502{
503 iterator it = begin() + oFirstPoint();
504 long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
505
506 for ( t = 0; t < tm; t++ )
507 {
508 for ( z = 0; z < zm; z++ )
509 {
510 for ( y = 0; y < ym; y++ )
511 {
512 for ( x = 0; x < xm; x++ )
513 *it++ = val;
514 it += oPointBetweenLine();
515 }
516 it += oLineBetweenSlice();
517 }
518 it += oSliceBetweenVolume();
519 }
520 return *this;
521}
522
523
524template<typename T>
525inline
527{
528 return _volume;
529}
530
531
532template<typename T>
533inline
535{
536 return _volume;
537}
538
539
540template<typename T>
541inline
543{
544 return _volume->getSizeX();
545}
546
547
548template<typename T>
549inline
551{
552 return _volume->getSizeY();
553}
554
555
556template<typename T>
557inline
559{
560 return _volume->getSizeZ();
561}
562
563
564template<typename T>
565inline
567{
568 return _volume->getSizeT();
569}
570
571
572template < typename T >
573inline
575{
576 std::vector<float> vs = _volume->getVoxelSize();
577 if( vs.size() >= 1 )
578 return vs[0];
579
580 return 1;
581}
582
583
584template < typename T >
585inline
587{
588 std::vector<float> vs = _volume->getVoxelSize();
589 if( vs.size() >= 2 )
590 return vs[1];
591
592 return 1;
593}
594
595
596template < typename T >
597inline
599{
600 std::vector<float> vs = _volume->getVoxelSize();
601 if( vs.size() >= 3 )
602 return vs[2];
603
604 return 1;
605}
606
607
608template < typename T >
609inline
611{
612 std::vector<float> vs = _volume->getVoxelSize();
613 if( vs.size() >= 4 )
614 return vs[3];
615
616 return 1;
617}
618
619
620template < typename T >
621inline
622void AimsData<T>::setSizeX( float sizex )
623{
624 std::vector<float> vs = _volume->getVoxelSize();
625 if( vs.size() == 0 )
626 vs.push_back( 1. );
627 vs[0] = sizex;
628 _volume->setVoxelSize( vs );
629}
630
631
632template < typename T >
633inline
634void AimsData<T>::setSizeY( float sizey )
635{
636 std::vector<float> vs = _volume->getVoxelSize();
637 while( vs.size() < 2 )
638 vs.push_back( 1. );
639 vs[1] = sizey;
640 _volume->setVoxelSize( vs );
641}
642
643
644template < typename T >
645inline
646void AimsData<T>::setSizeZ( float sizez )
647{
648 std::vector<float> vs = _volume->getVoxelSize();
649 while( vs.size() < 3 )
650 vs.push_back( 1. );
651 vs[2] = sizez;
652 _volume->setVoxelSize( vs );
653}
654
655
656template < typename T >
657inline
658void AimsData<T>::setSizeT( float sizet )
659{
660 std::vector<float> vs = _volume->getVoxelSize();
661 while( vs.size() < 4 )
662 vs.push_back( 1. );
663 vs[3] = sizet;
664 _volume->setVoxelSize( vs );
665}
666
667
668template < typename T >
669inline
670void
671AimsData<T>::setSizeXYZT( float sizex, float sizey, float sizez, float sizet )
672{
673 _volume->setVoxelSize( sizex, sizey, sizez, sizet );
674}
675
676
677template < typename T >
678inline
680{
681 _volume->setVoxelSize( other.volume()->getVoxelSize() );
682}
683
684
685template < typename T >
686inline
687const carto::AllocatorContext & AimsData<T>::allocator() const
688{
689 return _volume->allocatorContext();
690}
691
692
693template < typename T >
694inline
696{
697 // allow to rebuild the header in this (non-const) if needed.
698 return const_cast< AimsData<T> & >( *this ).header();
699}
700
701
702template < typename T >
703inline
705{
706 if( !dynamic_cast<aims::PythonHeader *>( d->header )
707 || &dynamic_cast<aims::PythonHeader *>( d->header )->getValue()
708 != &_volume->header() )
709 {
710 // the header is out of date, maybe because the underlying Volume has
711 // reallocated a new one. We have to rebuild it
712 delete d->header;
713 d->header = new aims::PythonHeader( *_volume );
714 }
715 return d->header;
716}
717
718
719template<typename T>
720inline
722{
723 if( hdr != header() )
724 {
726 if( !d->header )
727 {
728 d->header = mh = new aims::PythonHeader( *_volume );
729 }
730 else
731 {
732 mh = static_cast<aims::PythonHeader *>( d->header );
733 carto::Object oldvs;
734 try
735 {
736 // retreive old voxel size (if any)
737 oldvs = mh->getProperty( "voxel_size" );
738 }
739 catch( ... )
740 {
741 }
742 mh->clearProperties();
743 if( !oldvs.isNull() )
744 /* keep old voxel size which was not part of the dynamic header
745 in the old AimsData */
746 mh->setProperty( "voxel_size", oldvs );
747 }
748 const aims::PythonHeader
749 *ph = dynamic_cast<const aims::PythonHeader *>( hdr );
750 if( ph )
751 mh->copy( *ph, 1 );
752 // hdr used to transfer ownership to me
753 delete hdr;
754 }
755}
756
757
758template < typename T >
759inline
762{
763 return *( begin() + n );
764}
765
766
767template < typename T >
768inline
771{
772 return *( begin() + n );
773}
774
775
776template < typename T >
777inline
781{
782 return (*_volume)( x, y, z, t );
783}
784
785
786template < typename T >
787inline
791 AimsData<T>::size_type t ) const
792{
793 return (*_volume)( x, y, z, t );
794}
795
796
797template < typename T >
798inline
801{
802 return (*this)( pt[0], pt[1], pt[2], pt[3] );
803}
804
805
806template < typename T >
807inline
810{
811 return (*this)( pt[0], pt[1], pt[2], pt[3] );
812}
813
814
815template < typename T >
816inline
819{
820 return (*this)( pt[0], pt[1], pt[2], pt[3] );
821}
822
823
824template < typename T >
825inline
828{
829 return (*this)( pt[0], pt[1], pt[2], pt[3] );
830}
831
832
833template < typename T >
834inline
837{
838 return (*this)( pt[0], pt[1], pt[2] );
839}
840
841
842template < typename T >
843inline
846{
847 return (*this)( pt[0], pt[1], pt[2] );
848}
849
850
851template < typename T >
852inline
855{
856 return (*this)( pt[0], pt[1], pt[2] );
857}
858
859
860template < typename T >
861inline
864{
865 return (*this)( pt[0], pt[1], pt[2] );
866}
867
868
869template < typename T >
870inline
873{
874 return (*this)( pt[0], pt[1] );
875}
876
877
878template < typename T >
879inline
882{
883 return (*this)( pt[0], pt[1] );
884}
885
886
887template < typename T >
888inline
891{
892 return (*this)( pt[0], pt[1] );
893}
894
895
896template < typename T >
897inline
900{
901 return (*this)( pt[0], pt[1] );
902}
903
904
905template < typename T >
906inline
908{
909 return volume()->min();
910}
911
912
913template < typename T >
914inline
916{
917 return volume()->max();
918}
919
920
921template < typename T >
922inline
923T AimsData<T>::minIndex( int* xx, int* yy, int* zz, int* tt ) const
924{
925 int minxind = 0,minyind = 0,minzind = 0,mintind = 0;
926 T mini;
928
929 mini = *it;
930 int x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
931
932 for ( t = 0; t < tm; t++ )
933 {
934 for ( z = 0; z < zm; z++ )
935 {
936 for ( y = 0; y < ym; y++ )
937 {
938 for ( x = 0; x < xm; x++ )
939 {
940 if ( *it < mini )
941 {
942 mini = *it;
943 minxind = x;
944 minyind = y;
945 minzind = z;
946 mintind = t;
947 }
948 it++;
949 }
950 it += oPointBetweenLine();
951 }
952 it += oLineBetweenSlice();
953 }
954 it += oSliceBetweenVolume();
955 }
956 if ( xx )
957 *xx = minxind;
958 if ( yy )
959 *yy = minyind;
960 if ( zz )
961 *zz = minzind;
962 if ( tt )
963 *tt = mintind;
964
965 return mini;
966}
967
968
969template < typename T >
970inline
971T AimsData<T>::maxIndex( int* xx, int* yy, int* zz, int* tt ) const
972{
973 int maxxind = 0,maxyind = 0,maxzind = 0,maxtind = 0;
974 T maxi;
976
977 maxi = *it;
978 int x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
979
980 for ( t = 0; t < tm; t++ )
981 {
982 for ( z = 0; z < zm; z++ )
983 {
984 for ( y = 0; y < ym; y++ )
985 {
986 for ( x = 0; x < xm; x++ )
987 {
988 if ( *it > maxi )
989 {
990 maxi = *it;
991 maxxind = x;
992 maxyind = y;
993 maxzind = z;
994 maxtind = t;
995 }
996 it++;
997 }
998 it += oPointBetweenLine();
999 }
1000 it += oLineBetweenSlice();
1001 }
1002 it += oSliceBetweenVolume();
1003 }
1004 if ( xx )
1005 *xx = maxxind;
1006 if ( yy )
1007 *yy = maxyind;
1008 if ( zz )
1009 *zz = maxzind;
1010 if ( tt )
1011 *tt = maxtind;
1012
1013 return maxi;
1014}
1015
1016
1017template < typename T >
1018inline
1019void AimsData<T>::fillBorder( const T& val )
1020{
1021 carto::VolumeRef<T> bigger = _volume->refVolume();
1022 if( bigger.isNull() )
1023 return;
1024 T *it;
1025 long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1026 long of = &_volume->at( 0, 0, 0, 0 ) - &bigger->at( 0, 0, 0, 0 ),
1027 op = &_volume->at( 0, 1, 0, 0 ) - &_volume->at( xm, 0, 0, 0 ),
1028 ol = &_volume->at( 0, 0, 1, 0 ) - &_volume->at( 0, ym, 0, 0 );
1029
1030 for ( t = 0; t < tm; t++ )
1031 {
1032 it = &bigger->at( 0, 0, 0, t );
1033 for ( x = 0; x < of; x++ )
1034 *it++ = val;
1035 for ( z = 0; z < zm; z++ )
1036 {
1037 for ( y = 0; y < ym; y++ )
1038 {
1039 it += xm;
1040 for ( x = 0; x < op; x++ )
1041 *it++ = val;
1042 }
1043 for ( x = 0; x < ol; x++ )
1044 *it++ = val;
1045 }
1046 for ( x = 0; x < of - op - ol; x++ )
1047 *it++ = val;
1048 }
1049}
1050
1051
1052template<typename T>
1054{
1055 AimsData<T> dat( *this );
1056 if( !_volume->refVolume().isNull() )
1057 {
1058 // border has to be copied
1060 _volume->refVolume()->getSizeX(), _volume->refVolume()->getSizeY(),
1061 _volume->refVolume()->getSizeZ(), _volume->refVolume()->getSizeT(),
1062 _volume->refVolume()->allocatorContext(),
1063 _volume->refVolume()->allocatorContext().isAllocated() ) );
1064
1065 if( _volume->refVolume()->allocatorContext().isAllocated() )
1066 transfer( _volume->refVolume(), rvol );
1067
1068 dat._volume.reset( new carto::Volume<T>( rvol, _volume->posInRefVolume(),
1069 typename carto::Volume<T>::Position4Di( _volume->getSizeX(),
1070 _volume->getSizeY(),
1071 _volume->getSizeZ(),
1072 _volume->getSizeT() ) ) );
1073 dat._volume->header().copyProperties(
1074 carto::Object::reference( _volume->header() ) );
1075 }
1076 else
1077 dat._volume.reset( new carto::Volume<T>( *_volume ) );
1078 delete dat.d->header;
1079 dat.d->header = new aims::PythonHeader( *dat._volume );
1080
1081 return dat;
1082}
1083
1084
1085template < typename T >
1086inline
1088{
1089 ASSERT( dimT() == 1 && other.dimT() == 1 &&
1090 dimZ() == 1 && other.dimZ() == 1 );
1091 ASSERT( dimY() == other.dimX() );
1092
1093 AimsData<T> prod( dimX(), other.dimY(), 1, 1,
1094 std::max( borderWidth(), other.borderWidth() ) );
1095 for ( long y = 0; y < other.dimY(); y++ )
1096 for ( long x = 0; x < dimX(); x++ )
1097 {
1098 prod( x, y ) = T( 0 );
1099 for ( long k = 0; k < dimY(); k++ )
1100 prod( x, y ) += (*this)( x, k ) * other( k, y );
1101 }
1102
1103 return prod;
1104}
1105
1106
1107template < typename T >
1108inline
1110{
1111 AimsData<T> tmp( dimY(), dimX(), dimZ(), dimT(), borderWidth() );
1113 *ph = dynamic_cast<aims::PythonHeader *>( header() );
1114 if( ph )
1115 {
1116 ph = static_cast<aims::PythonHeader *>( ph->cloneHeader() );
1117 if( ph->hasProperty( "volume_dimension" ) )
1118 ph->removeProperty( "volume_dimension" );
1119 if( ph->hasProperty( "voxel_size" ) )
1120 ph->removeProperty( "voxel_size" );
1121 tmp.setHeader( ph );
1122 }
1123 tmp.setSizeXYZT( sizeY(), sizeX(), sizeZ(), sizeT() );
1124 tmp.fillBorder( T( 0 ) );
1125
1126 long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1127
1128 for ( t = 0; t < tm; t++ )
1129 for ( z = 0; z < zm; z++ )
1130 for ( y = 0; y < ym; y++ )
1131 for ( x = 0; x < xm; x++ )
1132 tmp( y, x, z, t ) = (*this)( x, y, z, t );
1133
1134 *this = tmp;
1135 return *this;
1136}
1137
1138
1139template < typename T >
1140inline
1142{
1143 std::vector<int> borders = _volume->getBorders();
1144 int s = borders.size();
1145 if (s > 0)
1146 {
1147 int width;
1148 width = borders[0];
1149 for( int i = 1; i < s; ++i )
1150 width = std::min( width, borders[i] );
1151 return width;
1152 }
1153 return 0;
1154}
1155
1156
1157template < typename T >
1158inline
1159const std::vector<int> & AimsData<T>::borders() const
1160{
1161 return _volume->getBorders();
1162}
1163
1164
1165template < typename T >
1166inline
1168{
1169 if( _volume->refVolume().isNull() )
1170 return 0;
1171 return &_volume->at(0) - &_volume->refVolume()->at( 0 );
1172}
1173
1174
1175template < typename T >
1176inline int AimsData<T>::oLine() const
1177{
1178 return &_volume->at( 0, 1 ) - &_volume->at( 0 );
1179}
1180
1181
1182template < typename T >
1183inline
1185{
1186 return &_volume->at( 0, 1 ) - &_volume->at( _volume->getSizeX() );
1187}
1188
1189
1190template < typename T >
1191inline
1193{
1194 return &_volume->at( 0, 0, 1 ) - &_volume->at( 0 );
1195}
1196
1197
1198template < typename T >
1199inline
1201{
1202 return &_volume->at( 0, 0, 1 ) - &_volume->at( 0, _volume->getSizeY() );
1203}
1204
1205
1206template < typename T >
1207inline
1209{
1210 return &_volume->at( 0, 0, 0, 1 ) - &_volume->at( 0 );
1211}
1212
1213
1214template < typename T >
1215inline
1217{
1218 return &_volume->at( 0, 0, 0, 1 )
1219 - &_volume->at( 0, 0, _volume->getSizeZ() );
1220}
1221
1222
1223template < typename T >
1224inline
1226 const AimsData<T>& secondThing )
1227{
1229 v += carto::VolumeRef<T>(secondThing.volume());
1230 return v;
1231}
1232
1233
1234template < typename T >
1235inline
1237 const AimsData<T>& secondThing )
1238{
1240 v -= carto::VolumeRef<T>(secondThing.volume());
1241 return v;
1242}
1243
1244template < typename T >
1245inline
1246AimsData<T> operator * ( const AimsData<T>& firstThing, float scale )
1247{
1249 v *= scale;
1250 return v;
1251}
1252
1253
1254// macros
1255
1256#define ForEach4d( thing , x , y , z , t) \
1257 for ( t = 0; t < thing.dimT(); t++ ) \
1258 for ( z = 0; z < thing.dimZ(); z++ ) \
1259 for ( y = 0; y < thing.dimY(); y++ ) \
1260 for ( x = 0; x < thing.dimX(); x++ )
1261
1262#define ForEach3d( thing , x , y , z) \
1263 for ( z = 0; z < thing.dimZ(); z++ ) \
1264 for ( y = 0; y < thing.dimY(); y++ ) \
1265 for ( x = 0; x < thing.dimX(); x++ )
1266
1267#define ForEach2d( thing , x , y) \
1268 for ( y = 0; y < thing.dimY(); y++ ) \
1269 for ( x = 0; x < thing.dimX(); x++ )
1270
1271#define ForEach1d( thing , x) \
1272 for ( x = 0; x < thing.dimX(); x++ )
1273
1274
1275#define ForEach4dp( thing , x , y , z , t) \
1276 for ( t = 0; t < thing->dimT(); t++ ) \
1277 for ( z = 0; z < thing->dimZ(); z++ ) \
1278 for ( y = 0; y < thing->dimY(); y++ ) \
1279 for ( x = 0; x < thing->dimX(); x++ )
1280
1281#define ForEach3dp( thing , x , y , z) \
1282 for ( z = 0; z < thing->dimZ(); z++ ) \
1283 for ( y = 0; y < thing->dimY(); y++ ) \
1284 for ( x = 0; x < thing->dimX(); x++ )
1285
1286#define ForEach2dp( thing , x , y) \
1287 for ( y = 0; y < thing->dimY(); y++ ) \
1288 for ( x = 0; x < thing->dimX(); x++ )
1289
1290#define ForEach1dp( thing , x) \
1291 for ( x = 0; x < thing->dimX(); x++ )
1292
1293
1294class DtiTensor;
1295
1296namespace carto
1297{
1298 // instanciations of Volume classes
1299
1300 extern template class VolumeProxy<DtiTensor*>;
1301 extern template class Volume<DtiTensor*>;
1302
1303}
1304
1305
1306#endif
1307
#define ASSERT(EX)
AimsData< T > operator*(const AimsData< T > &firstThing, float scale)
AimsData< T > operator-(const AimsData< T > &firstThing, const AimsData< T > &secondThing)
AimsData< T > operator+(const AimsData< T > &firstThing, const AimsData< T > &secondThing)
T & reference
basic reference
AimsData(const AimsData< T > &other)
int oVolume() const
Offset between 2 consecutive volumes.
T **** pointer4d
4D-pointer
void setSizeY(float sizey)
int borderWidth() const
Size of the border.
int oSlice() const
Offset between 2 consecutive slices.
const carto::AllocatorContext & allocator() const
reference operator()(size_type x=0, size_type y=0, size_type z=0, size_type t=0)
T maxIndex(int *x, int *y, int *z, int *t) const
T minIndex(int *x, int *y, int *z, int *t) const
void setSizeT(float sizet)
AimsData(const AimsData< T > &other, int borderw)
void setHeader(aims::Header *hdr)
carto::VolumeRef< T > & volume()
const carto::VolumeRef< T > & volume() const
AimsData< T > & transpose()
float sizeX() const
int oLineBetweenSlice() const
Number of lines between 2 consecutive slices.
T * pointer
basic pointer
size_t size_type
size of the basic type
void setSizeXYZT(const AimsData< T > &other)
void setSizeXYZT(float sizex=1.0f, float sizey=1.0f, float sizez=1.0f, float sizet=1.0f)
T * iterator
basic iterator
int oLine() const
Offset between 2 consecutive lines.
AimsData< T > & operator=(const carto::rc_ptr< carto::Volume< T > > &vol)
float sizeT() const
const_iterator end() const
AimsData< T > clone() const
virtual ~AimsData()
int dimY() const
const T * const_iterator
basic constant iterator
T minimum() const
int dimX() const
const std::vector< int > & borders() const
Sizes of the border.
ptrdiff_t difference_type
difference type
int oFirstPoint() const
Offset from the start of the allocated memory to the first point.
T maximum() const
AimsData< T > cross(const AimsData< T > &other)
bool empty() const
AimsData(const carto::rc_ptr< carto::Volume< T > > &vol)
const T & const_reference
basic constant reference
int dimT() const
float sizeZ() const
float sizeY() const
int dimZ() const
int oSliceBetweenVolume() const
Number of slices between 2 consecutive volumes.
int oPointBetweenLine() const
Offset between the end of a line and the start of the consecutive line.
reference operator[](size_type n)
const aims::Header * header() const
void setSizeZ(float sizez)
AimsData(int dimx=1, int dimy=1, int dimz=1, int dimt=1, int borderw=0)
AimsData(int dimx, int dimy, int dimz, int dimt, int borderw, const carto::AllocatorContext &al)
AimsData(const carto::VolumeRef< T > &vol)
iterator end()
iterator begin()
void fillBorder(const T &val)
aims::Header * header()
void setSizeX(float sizex)
const_iterator begin() const
Attributed python-like header, stores all needed information about an object, currently used for volu...
Definition pheader.h:52
virtual void copy(const PythonHeader &, bool keepUuid=false)
virtual Header * cloneHeader(bool keepUuid=false) const
std::string name()
std::string dataType()
virtual void copyProperties(Object source)
Object reference(Object &value)
virtual T & getValue()
virtual void clearProperties()
virtual bool getProperty(const std::string &, Object &) const
virtual bool removeProperty(const std::string &)
virtual void setProperty(const std::string &, Object)
virtual bool hasProperty(const std::string &) const
std::vector< float > getVoxelSize() const
rc_ptr< Volume< T > > refVolume() const
const T & at(long x, long y=0, long z=0, long t=0) const
const PropertySet & header() const
int getSizeX() const
VolumeRef< T > deepcopy() const
bool isNull() const
void reset(T *p=NULL)
carto::Object getObjectHeader(Headered &h)
void transfer(const Volume< T > &src, Volume< T > &dst)
aims::Header * header
AimsVector< int16_t, 3 > Point3d
AimsVector< int64_t, 4 > Point4dl
AimsVector< int64_t, 3 > Point3dl
AimsVector< int16_t, 2 > Point2d
AimsVector< int64_t, 2 > Point2dl
AimsVector< int16_t, 4 > Point4d