aimsdata  5.1.2
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 
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 
68 template<typename T>
69 class
70 // #ifndef AIMSDATA_CLASS_NO_DEPREC_WARNING
71 // __attribute__((__deprecated__("use carto::VolumeRef() instead")))
72 // #endif
73  AimsData : public carto::RCObject
74 {
75 
76 public:
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 
119  const carto::VolumeRef<T> & volume() const;
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;
144  void setHeader( aims::Header* hdr );
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 );
169  AimsData<T> clone () const;
170  AimsData<T> cross( const AimsData<T>& other );
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;
190  int oSliceBetweenVolume() 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 
204 namespace 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>
222  {
223  return carto::Object::reference( obj.volume()->header() );
224  }
225 
226 }
227 
228 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES
229 
230 // private struct
231 
232 template<typename T>
233 struct AimsData<T>::Private
234 {
235  Private();
236  ~Private();
237 
239 
241 };
242 
243 
244 // inline methods definition
245 
246 // Private struct methods
247 
248 template<typename T>
249 inline
251  : header( 0 )
252 {
253 }
254 
255 
256 template<typename T>
257 inline
259 {
260  if( header )
261  delete header;
262 }
263 
264 
265 template<typename T>
266 inline
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 
292 template <typename T>
294 {
295  return _volume;
296 }
297 
298 
299 template <typename T>
301 {
302  return _volume;
303 }
304 
305 
306 template <typename T>
308 {
309  return _volume;
310 }
311 
312 
313 template <typename T>
315 {
316  return _volume;
317 }
318 
319 
320 template<typename T>
321 inline
323 {
324  return &*_volume->begin();
325 }
326 
327 
328 template<typename T>
329 inline
331 {
332  return &*_volume->begin();
333 }
334 
335 
336 template<typename T>
337 inline
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 
347 template<typename T>
348 inline
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 
358 template<typename T>
359 inline
360 bool AimsData<T>::empty() const
361 {
362  return _volume->begin() == _volume->end();
363 }
364 
365 template<typename T>
366 inline
367 AimsData<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 
382 template < typename T >
383 inline
384 AimsData<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 
400 template < typename T >
401 inline
403  : carto::RCObject(),
404  _volume( other._volume ),
405  d( new Private )
406 {
407  d->header = new aims::PythonHeader( *_volume );
408 }
409 
410 
411 template < typename T >
412 inline
413 AimsData<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 
438 template < typename T >
439 inline
441 {
442  delete d;
443 }
444 
445 
446 template < typename T >
447 inline
449  : carto::RCObject(),
450  _volume( vol ),
451  d( new Private )
452 {
453  d->header = new aims::PythonHeader( *_volume );
454 }
455 
456 template < typename T >
457 inline
459  : carto::RCObject(),
460  _volume( vol ),
461  d( new Private )
462 {
463  d->header = new aims::PythonHeader( *_volume );
464 }
465 
466 
467 template < typename T >
468 inline
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 
483 template < typename T >
484 inline
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 
499 template < typename T >
500 inline
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 
524 template<typename T>
525 inline
527 {
528  return _volume;
529 }
530 
531 
532 template<typename T>
533 inline
535 {
536  return _volume;
537 }
538 
539 
540 template<typename T>
541 inline
542 int AimsData<T>::dimX() const
543 {
544  return _volume->getSizeX();
545 }
546 
547 
548 template<typename T>
549 inline
550 int AimsData<T>::dimY() const
551 {
552  return _volume->getSizeY();
553 }
554 
555 
556 template<typename T>
557 inline
558 int AimsData<T>::dimZ() const
559 {
560  return _volume->getSizeZ();
561 }
562 
563 
564 template<typename T>
565 inline
566 int AimsData<T>::dimT() const
567 {
568  return _volume->getSizeT();
569 }
570 
571 
572 template < typename T >
573 inline
574 float AimsData<T>::sizeX() const
575 {
576  std::vector<float> vs = _volume->getVoxelSize();
577  if( vs.size() >= 1 )
578  return vs[0];
579 
580  return 1;
581 }
582 
583 
584 template < typename T >
585 inline
586 float AimsData<T>::sizeY() const
587 {
588  std::vector<float> vs = _volume->getVoxelSize();
589  if( vs.size() >= 2 )
590  return vs[1];
591 
592  return 1;
593 }
594 
595 
596 template < typename T >
597 inline
598 float AimsData<T>::sizeZ() const
599 {
600  std::vector<float> vs = _volume->getVoxelSize();
601  if( vs.size() >= 3 )
602  return vs[2];
603 
604  return 1;
605 }
606 
607 
608 template < typename T >
609 inline
610 float AimsData<T>::sizeT() const
611 {
612  std::vector<float> vs = _volume->getVoxelSize();
613  if( vs.size() >= 4 )
614  return vs[3];
615 
616  return 1;
617 }
618 
619 
620 template < typename T >
621 inline
622 void 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 
632 template < typename T >
633 inline
634 void 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 
644 template < typename T >
645 inline
646 void 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 
656 template < typename T >
657 inline
658 void 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 
668 template < typename T >
669 inline
670 void
671 AimsData<T>::setSizeXYZT( float sizex, float sizey, float sizez, float sizet )
672 {
673  _volume->setVoxelSize( sizex, sizey, sizez, sizet );
674 }
675 
676 
677 template < typename T >
678 inline
680 {
681  _volume->setVoxelSize( other.volume()->getVoxelSize() );
682 }
683 
684 
685 template < typename T >
686 inline
687 const carto::AllocatorContext & AimsData<T>::allocator() const
688 {
689  return _volume->allocatorContext();
690 }
691 
692 
693 template < typename T >
694 inline
696 {
697  // allow to rebuild the header in this (non-const) if needed.
698  return const_cast< AimsData<T> & >( *this ).header();
699 }
700 
701 
702 template < typename T >
703 inline
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 
719 template<typename T>
720 inline
722 {
723  if( hdr != header() )
724  {
725  aims::PythonHeader *mh;
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 
758 template < typename T >
759 inline
760 typename AimsData<T>::reference
762 {
763  return *( begin() + n );
764 }
765 
766 
767 template < typename T >
768 inline
771 {
772  return *( begin() + n );
773 }
774 
775 
776 template < typename T >
777 inline
778 typename AimsData<T>::reference
781 {
782  return (*_volume)( x, y, z, t );
783 }
784 
785 
786 template < typename T >
787 inline
791  AimsData<T>::size_type t ) const
792 {
793  return (*_volume)( x, y, z, t );
794 }
795 
796 
797 template < typename T >
798 inline
799 typename AimsData<T>::reference
801 {
802  return (*this)( pt[0], pt[1], pt[2], pt[3] );
803 }
804 
805 
806 template < typename T >
807 inline
810 {
811  return (*this)( pt[0], pt[1], pt[2], pt[3] );
812 }
813 
814 
815 template < typename T >
816 inline
817 typename AimsData<T>::reference
819 {
820  return (*this)( pt[0], pt[1], pt[2], pt[3] );
821 }
822 
823 
824 template < typename T >
825 inline
828 {
829  return (*this)( pt[0], pt[1], pt[2], pt[3] );
830 }
831 
832 
833 template < typename T >
834 inline
835 typename AimsData<T>::reference
837 {
838  return (*this)( pt[0], pt[1], pt[2] );
839 }
840 
841 
842 template < typename T >
843 inline
846 {
847  return (*this)( pt[0], pt[1], pt[2] );
848 }
849 
850 
851 template < typename T >
852 inline
853 typename AimsData<T>::reference
855 {
856  return (*this)( pt[0], pt[1], pt[2] );
857 }
858 
859 
860 template < typename T >
861 inline
864 {
865  return (*this)( pt[0], pt[1], pt[2] );
866 }
867 
868 
869 template < typename T >
870 inline
871 typename AimsData<T>::reference
873 {
874  return (*this)( pt[0], pt[1] );
875 }
876 
877 
878 template < typename T >
879 inline
882 {
883  return (*this)( pt[0], pt[1] );
884 }
885 
886 
887 template < typename T >
888 inline
889 typename AimsData<T>::reference
891 {
892  return (*this)( pt[0], pt[1] );
893 }
894 
895 
896 template < typename T >
897 inline
900 {
901  return (*this)( pt[0], pt[1] );
902 }
903 
904 
905 template < typename T >
906 inline
908 {
909  return volume()->min();
910 }
911 
912 
913 template < typename T >
914 inline
916 {
917  return volume()->max();
918 }
919 
920 
921 template < typename T >
922 inline
923 T 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;
927  const_iterator it = begin() + oFirstPoint();
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 
969 template < typename T >
970 inline
971 T 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;
975  const_iterator it = begin() + oFirstPoint();
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 
1017 template < typename T >
1018 inline
1019 void 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 
1052 template<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 
1085 template < typename T >
1086 inline
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 
1107 template < typename T >
1108 inline
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 
1139 template < typename T >
1140 inline
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 
1157 template < typename T >
1158 inline
1159 const std::vector<int> & AimsData<T>::borders() const
1160 {
1161  return _volume->getBorders();
1162 }
1163 
1164 
1165 template < typename T >
1166 inline
1168 {
1169  if( _volume->refVolume().isNull() )
1170  return 0;
1171  return &_volume->at(0) - &_volume->refVolume()->at( 0 );
1172 }
1173 
1174 
1175 template < typename T >
1176 inline int AimsData<T>::oLine() const
1177 {
1178  return &_volume->at( 0, 1 ) - &_volume->at( 0 );
1179 }
1180 
1181 
1182 template < typename T >
1183 inline
1185 {
1186  return &_volume->at( 0, 1 ) - &_volume->at( _volume->getSizeX() );
1187 }
1188 
1189 
1190 template < typename T >
1191 inline
1193 {
1194  return &_volume->at( 0, 0, 1 ) - &_volume->at( 0 );
1195 }
1196 
1197 
1198 template < typename T >
1199 inline
1201 {
1202  return &_volume->at( 0, 0, 1 ) - &_volume->at( 0, _volume->getSizeY() );
1203 }
1204 
1205 
1206 template < typename T >
1207 inline
1209 {
1210  return &_volume->at( 0, 0, 0, 1 ) - &_volume->at( 0 );
1211 }
1212 
1213 
1214 template < typename T >
1215 inline
1217 {
1218  return &_volume->at( 0, 0, 0, 1 )
1219  - &_volume->at( 0, 0, _volume->getSizeZ() );
1220 }
1221 
1222 
1223 template < typename T >
1224 inline
1226  const AimsData<T>& secondThing )
1227 {
1229  v += carto::VolumeRef<T>(secondThing.volume());
1230  return v;
1231 }
1232 
1233 
1234 template < typename T >
1235 inline
1237  const AimsData<T>& secondThing )
1238 {
1240  v -= carto::VolumeRef<T>(secondThing.volume());
1241  return v;
1242 }
1243 
1244 template < typename T >
1245 inline
1246 AimsData<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 
1294 class DtiTensor;
1295 
1296 namespace 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, const AimsData< T > &secondThing)
AimsData< T > operator*(const AimsData< T > &firstThing, float scale)
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
int getSizeZ() const
std::vector< float > getVoxelSize() const
VolumeRef< T > deepcopy() const
virtual void copyHeaderFrom(const PropertySet &other)
int getSizeT() const
iterator end()
rc_ptr< Volume< T > > refVolume() const
const T & at(long x, long y=0, long z=0, long t=0) const
int getSizeY() const
const PropertySet & header() const
iterator begin()
int getSizeX() 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
static int borderWidth(carto::rc_ptr< carto::Volume< T > > vol)