A.I.M.S


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/border/border.h>
41 #include <aims/rgb/rgb.h>
42 #include <cartobase/smart/rcptr.h>
44 #include <aims/data/pheader.h>
45 
46 
47 template<typename T>
48 class AimsData : public carto::RCObject, public aims::Border
49 {
50  public:
51  typedef T value_type;
53  typedef T* pointer;
55  typedef T**** pointer4d;
57  typedef T* iterator;
59  typedef const T* const_iterator;
61  typedef T& reference;
63  typedef const T& const_reference;
65  typedef size_t size_type;
67  typedef ptrdiff_t difference_type;
68 
69  iterator begin();
70  const_iterator begin() const;
71  iterator end();
72  const_iterator end() const;
73  bool empty() const;
74 
75  AimsData( int dimx = 1, int dimy = 1, int dimz = 1, int dimt = 1,
76  int borderw = 0 );
77  AimsData( int dimx, int dimy, int dimz, int dimt,
78  int borderw, const carto::AllocatorContext & al );
79  AimsData( const AimsData<T>& other );
80  AimsData( const AimsData<T>& other, int borderw );
81  virtual ~AimsData();
82 
83  // conversions with carto::Volume
86 
87  AimsData<T> & operator = ( const AimsData<T> & );
88  AimsData<T> & operator = ( const T & );
89 
93  operator carto::rc_ptr<carto::Volume<T> >();
94  operator const carto::rc_ptr<carto::Volume<T> >() const;
95 
96  const carto::AllocatorContext & allocator() const;
97  int dimX() const;
98  int dimY() const;
99  int dimZ() const;
100  int dimT() const;
101  float sizeX() const;
102  float sizeY() const;
103  float sizeZ() const;
104  float sizeT() const;
105  void setSizeX( float sizex );
106  void setSizeY( float sizey );
107  void setSizeZ( float sizez );
108  void setSizeT( float sizet );
109  void setSizeXYZT( float sizex = 1.0f, float sizey = 1.0f,
110  float sizez = 1.0f, float sizet = 1.0f );
111  void setSizeXYZT( const AimsData<T>& other );
112  const aims::Header* header() const;
113  aims::Header* header();
114  void setHeader( aims::Header* hdr );
118  size_type z = 0, size_type t = 0 );
120  size_type z = 0, size_type t = 0 ) const;
121  reference operator () ( const Point4d& pt );
122  const_reference operator () ( const Point4d& pt ) const;
123  reference operator () ( const Point4dl& pt );
124  const_reference operator () ( const Point4dl& pt ) const;
125  reference operator () ( const Point3d& pt );
126  const_reference operator () ( const Point3d& pt ) const;
127  reference operator () ( const Point3dl& pt );
128  const_reference operator () ( const Point3dl& pt ) const;
129  reference operator () ( const Point2d& pt );
130  const_reference operator () ( const Point2d& pt ) const;
131  reference operator () ( const Point2dl& pt );
132  const_reference operator () ( const Point2dl& pt ) const;
133 
134  T minimum() const;
135  T maximum() const;
136  T minIndex( int* x, int* y, int* z, int* t ) const;
137  T maxIndex( int* x, int* y, int* z, int* t ) const;
138  void fillBorder( const T& val );
139  AimsData<T> clone () const;
140  AimsData<T> cross( const AimsData<T>& other );
142 
143  private:
144  struct Private;
145 
147  Private *d;
148 };
149 
150 
151 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
152 
153 namespace carto
154 {
155 
156  template<class T> class DataTypeCode<AimsData<T> >
157  {
158  public:
159  static std::string objectType()
160  { return "Volume"; }
161  static std::string dataType()
162  { return DataTypeCode<T>::dataType(); }
163  static std::string name()
164  {
165  return std::string("volume of ") + DataTypeCode< T >::name();
166  }
167  };
168 
169  template <typename T>
171  {
172  return carto::Object::reference( obj.volume()->header() );
173  }
174 
175 }
176 
177 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES
178 
179 // private struct
180 
181 template<typename T>
182 struct AimsData<T>::Private
183 {
184  Private();
185  ~Private();
186 
187  static int borderWidth( carto::rc_ptr<carto::Volume<T> > vol );
188 
190 };
191 
192 
193 // inline methods definition
194 
195 // Private struct methods
196 
197 template<typename T>
198 inline
200  : header( 0 )
201 {
202 }
203 
204 
205 template<typename T>
206 inline
208 {
209  if( header )
210  delete header;
211 }
212 
213 
214 template<typename T>
215 inline
217 {
218  if( !vol->refVolume().isNull() ) // is a view to another volume
219  {
220  // this is only the border in X direction, but we can't be more precise.
221  return ( vol->refVolume()->getSizeX() - vol->getSizeX() ) / 2;
222  }
223  return 0;
224 }
225 
226 
227 // AimsData methods
228 
229 template <typename T>
231 {
232  return volume();
233 }
234 
235 
236 template <typename T>
238 {
239  return volume();
240 }
241 
242 
243 template<typename T>
244 inline
246 {
247  return _volume->refVolume().isNull() ?
248  &*_volume->begin() :
249  &*_volume->refVolume()->begin(); // pointer to the border
250 }
251 
252 
253 template<typename T>
254 inline
256 {
257  return _volume->refVolume().isNull() ?
258  &*_volume->begin() :
259  &*_volume->refVolume()->begin(); // pointer to the border
260 }
261 
262 
263 template<typename T>
264 inline
266 {
267  carto::Volume<T> *vol = _volume->refVolume().isNull() ?
268  _volume.get() : _volume->refVolume().get();
269 #ifdef CARTO_USE_BLITZ
270  return &*vol->begin() + long(vol->getSizeX()) * vol->getSizeY()
271  * vol->getSizeZ() * vol->getSizeT();
272 #else
273  return &*_volume->end();
274 #endif
275 }
276 
277 
278 template<typename T>
279 inline
281 {
282  carto::Volume<T> *vol = _volume->refVolume().isNull() ?
283  _volume.get() : _volume->refVolume().get();
284 #ifdef CARTO_USE_BLITZ
285  return &*vol->begin() + long(vol->getSizeX()) * vol->getSizeY()
286  * vol->getSizeZ() * vol->getSizeT();
287 #else
288  return &*_volume->end();
289 #endif
290 }
291 
292 
293 template<typename T>
294 inline
295 bool AimsData<T>::empty() const
296 {
297  return _volume->begin() == _volume->end();
298 }
299 
300 
301 template<typename T>
302 inline
303 AimsData<T>::AimsData( int dimx, int dimy, int dimz, int dimt, int borderw )
304  : carto::RCObject(), aims::Border( dimx, dimy, dimz, borderw ),
305  _volume( new carto::Volume<T>( dimx + borderw * 2, dimy + borderw * 2,
306  dimz + borderw * 2, dimt ) ),
307  d( new Private )
308 {
309  if( borderw != 0 )
310  _volume.reset( new carto::Volume<T>(
311  _volume,
312  typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
313  typename carto::Volume<T>::Position4Di( dimx, dimy, dimz, dimt ) ) );
314  d->header = new aims::PythonHeader( *_volume );
315 }
316 
317 
318 template < typename T >
319 inline
320 AimsData<T>::AimsData( int dimx, int dimy, int dimz, int dimt,
321  int borderw, const carto::AllocatorContext & al )
322  : carto::RCObject(), aims::Border( dimx, dimy, dimz, borderw ),
323  _volume( new carto::Volume<T>( dimx + borderw * 2, dimy + borderw * 2,
324  dimz + borderw * 2, dimt, al ) ),
325  d( new Private )
326 {
327  if( borderw != 0 )
328  _volume.reset( new carto::Volume<T>(
329  _volume,
330  typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
331  typename carto::Volume<T>::Position4Di( dimx, dimy, dimz, dimt ), al ) );
332  d->header = new aims::PythonHeader( *_volume );
333 }
334 
335 
336 template < typename T >
337 inline
339  : carto::RCObject(), aims::Border( other.dimX(), other.dimY(),
340  other.dimZ(), other.borderWidth() ),
341  _volume( other._volume ),
342  d( new Private )
343 {
344  d->header = new aims::PythonHeader( *_volume );
345 }
346 
347 
348 template < typename T >
349 inline
350 AimsData<T>::AimsData( const AimsData<T>& other, int borderw )
351  : carto::RCObject(), aims::Border( other.dimX(), other.dimY(), other.dimZ(),
352  borderw ), _volume( new carto::Volume<T>( other.dimX() + borderw * 2,
353  other.dimY() + borderw * 2, other.dimZ() + borderw * 2, other.dimT() ) ),
354  d( new Private )
355 {
356  _volume->copyHeaderFrom( other.volume()->header() );
357 
358  if( borderw != 0 )
359  _volume.reset( new carto::Volume<T>(
360  _volume,
361  typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
362  typename carto::Volume<T>::Position4Di( other.dimX(), other.dimY(),
363  other.dimZ(), other.dimT() ) ) );
364  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
365  for ( t = 0; t < tm; t++ )
366  for ( z = 0; z < zm; z++ )
367  for ( y = 0; y < ym; y++ )
368  for ( x = 0; x < xm; x++ )
369  (*this)( x, y, z, t ) = other( x, y, z, t );
370  d->header = new aims::PythonHeader( *_volume );
371 }
372 
373 
374 template < typename T >
375 inline
377 {
378  delete d;
379 }
380 
381 
382 template < typename T >
383 inline
385  : carto::RCObject(),
386  aims::Border( vol->getSizeX(),
387  vol->getSizeY(),
388  vol->getSizeZ(),
389  Private::borderWidth( vol ) ),
390  _volume( vol ),
391  d( new Private )
392 {
393  d->header = new aims::PythonHeader( *_volume );
394 }
395 
396 
397 template < typename T >
398 inline
400 {
401  if( _volume.get() == vol.get() )
402  return *this;
403 
404  int border = Private::borderWidth( vol );
405  _setBorder( vol->getSizeX(), vol->getSizeY(),
406  vol->getSizeZ(), border );
407  delete d->header;
408  _volume = vol;
409  d->header = new aims::PythonHeader( *_volume );
410 
411  return *this;
412 }
413 
414 
415 template < typename T >
416 inline
418 {
419  if ( &other == this )
420  return *this;
421 
422  _setBorder( other.dimX(), other.dimY(), other.dimZ(), other.borderWidth() );
423  delete d->header;
424  _volume = other._volume;
425  *d = *other.d;
426  d->header = new aims::PythonHeader( *_volume );
427  return *this;
428 }
429 
430 
431 template < typename T >
432 inline
434 {
435  iterator it = begin() + oFirstPoint();
436  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
437 
438  for ( t = 0; t < tm; t++ )
439  {
440  for ( z = 0; z < zm; z++ )
441  {
442  for ( y = 0; y < ym; y++ )
443  {
444  for ( x = 0; x < xm; x++ )
445  *it++ = val;
446  it += oPointBetweenLine();
447  }
448  it += oLineBetweenSlice();
449  }
450  it += oSliceBetweenVolume();
451  }
452  return *this;
453 }
454 
455 
456 template<typename T>
457 inline
459 {
460  return _volume;
461 }
462 
463 
464 template<typename T>
465 inline
467 {
468  return _volume;
469 }
470 
471 
472 template<typename T>
473 inline
474 int AimsData<T>::dimX() const
475 {
476  return _volume->getSizeX();
477 }
478 
479 
480 template<typename T>
481 inline
482 int AimsData<T>::dimY() const
483 {
484  return _volume->getSizeY();
485 }
486 
487 
488 template<typename T>
489 inline
490 int AimsData<T>::dimZ() const
491 {
492  return _volume->getSizeZ();
493 }
494 
495 
496 template<typename T>
497 inline
498 int AimsData<T>::dimT() const
499 {
500  return _volume->getSizeT();
501 }
502 
503 
504 template < typename T >
505 inline
506 float AimsData<T>::sizeX() const
507 {
508  if( !d->header )
509  return 1;
510  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
511  if( !ph )
512  return 1;
513  try
514  {
515  carto::Object vs = ph->getProperty( "voxel_size" );
516  if( !vs.isNull() && vs->size() >= 1 )
517  return (float) vs->getArrayItem( 0 )->getScalar();
518  }
519  catch( ... )
520  {
521  }
522  return 1;
523 }
524 
525 
526 template < typename T >
527 inline
528 float AimsData<T>::sizeY() const
529 {
530  if( !d->header )
531  return 1;
532  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
533  if( !ph )
534  return 1;
535  try
536  {
537  carto::Object vs = ph->getProperty( "voxel_size" );
538  if( !vs.isNull() && vs->size() >= 2 )
539  return (float) vs->getArrayItem( 1 )->getScalar();
540  }
541  catch( ... )
542  {
543  }
544  return 1;
545 }
546 
547 
548 template < typename T >
549 inline
550 float AimsData<T>::sizeZ() const
551 {
552  if( !d->header )
553  return 1;
554  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
555  if( !ph )
556  return 1;
557  try
558  {
559  carto::Object vs = ph->getProperty( "voxel_size" );
560  if( !vs.isNull() && vs->size() >= 3 )
561  return (float) vs->getArrayItem( 2 )->getScalar();
562  }
563  catch( ... )
564  {
565  }
566  return 1;
567 }
568 
569 
570 template < typename T >
571 inline
572 float AimsData<T>::sizeT() const
573 {
574  if( !d->header )
575  return 1;
576  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
577  if( !ph )
578  return 1;
579  try
580  {
581  carto::Object vs = ph->getProperty( "voxel_size" );
582  if( !vs.isNull() && vs->size() >= 4 )
583  return (float) vs->getArrayItem( 3 )->getScalar();
584  }
585  catch( ... )
586  {
587  }
588  return 1;
589 }
590 
591 
592 template < typename T >
593 inline
594 void AimsData<T>::setSizeX( float sizex )
595 {
596  if( !d->header )
597  setHeader( new aims::PythonHeader );
598  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
599  if( ph )
600  {
601  try
602  {
603  carto::Object vs = ph->getProperty( "voxel_size" );
604  if( !vs.isNull() )
605  if( vs->size() >= 1 )
606  vs->setArrayItem( 0, carto::Object::value( sizex ) );
607  }
608  catch( ... )
609  {
610  std::vector<float> vs( 4, 1. );
611  vs[0] = sizex;
612  ph->setProperty( "voxel_size", vs );
613  }
614  }
615 }
616 
617 
618 template < typename T >
619 inline
620 void AimsData<T>::setSizeY( float sizey )
621 {
622  if( !d->header )
623  setHeader( new aims::PythonHeader );
624  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
625  if( ph )
626  {
627  std::vector<float> vs( 4, 1. );
628  try
629  {
630  carto::Object vso = ph->getProperty( "voxel_size" );
631  if( !vso.isNull() )
632  {
633  if( vso->size() >= 2 )
634  {
635  vso->setArrayItem( 1, carto::Object::value( sizey ) );
636  return;
637  }
638  else
639  {
640  if( vso->size() >= 1 )
641  vs[0] = vso->getArrayItem(0)->getScalar();
642  }
643  }
644  }
645  catch( ... )
646  {
647  }
648  vs[1] = sizey;
649  ph->setProperty( "voxel_size", vs );
650  }
651 }
652 
653 
654 template < typename T >
655 inline
656 void AimsData<T>::setSizeZ( float sizez )
657 {
658  if( !d->header )
659  setHeader( new aims::PythonHeader );
660  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
661  if( ph )
662  {
663  std::vector<float> vs( 4, 1. );
664  try
665  {
666  carto::Object vso = ph->getProperty( "voxel_size" );
667  if( !vso.isNull() )
668  {
669  if( vso->size() >= 3 )
670  {
671  vso->setArrayItem( 2, carto::Object::value( sizez ) );
672  return;
673  }
674  else
675  {
676  carto::Object it;
677  int i;
678  for( i=0, it=vso->objectIterator();
679  it->isValid() && i<3; ++i, it->next() )
680  vs[i] = it->currentValue()->getScalar();
681  }
682  }
683  }
684  catch( ... )
685  {
686  }
687  vs[2] = sizez;
688  ph->setProperty( "voxel_size", vs );
689  }
690 }
691 
692 
693 template < typename T >
694 inline
695 void AimsData<T>::setSizeT( float sizet )
696 {
697  if( !d->header )
698  setHeader( new aims::PythonHeader );
699  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
700  if( ph )
701  {
702  std::vector<float> vs( 4, 1. );
703  try
704  {
705  carto::Object vso = ph->getProperty( "voxel_size" );
706  if( !vso.isNull() )
707  {
708  if( vso->size() >= 4 )
709  {
710  vso->setArrayItem( 3, carto::Object::value( sizet ) );
711  return;
712  }
713  else
714  {
715  carto::Object it;
716  int i;
717  for( i=0, it=vso->objectIterator();
718  it->isValid() && i<4; ++i, it->next() )
719  vs[i] = it->currentValue()->getScalar();
720  }
721  }
722  }
723  catch( ... )
724  {
725  }
726  vs[3] = sizet;
727  ph->setProperty( "voxel_size", vs );
728  }
729 }
730 
731 
732 template < typename T >
733 inline
734 void
735 AimsData<T>::setSizeXYZT( float sizex, float sizey, float sizez, float sizet )
736 {
737  if( !d->header )
738  setHeader( new aims::PythonHeader );
739  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
740  if( ph )
741  {
742  std::vector<float> vs( 4 );
743  vs[0] = sizex;
744  vs[1] = sizey;
745  vs[2] = sizez;
746  vs[3] = sizet;
747  ph->setProperty( "voxel_size", vs );
748  }
749 }
750 
751 
752 template < typename T >
753 inline
755 {
756  if( !d->header )
757  setHeader( new aims::PythonHeader );
758  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
759  if( ph )
760  {
761  std::vector<float> vs( 4 );
762  vs[0] = other.sizeX();
763  vs[1] = other.sizeY();
764  vs[2] = other.sizeZ();
765  vs[3] = other.sizeT();
766  ph->setProperty( "voxel_size", vs );
767  }
768 }
769 
770 
771 template < typename T >
772 inline
773 const carto::AllocatorContext & AimsData<T>::allocator() const
774 {
775  return _volume->allocatorContext();
776 }
777 
778 
779 template < typename T >
780 inline
782 {
783  return d->header;
784 }
785 
786 
787 template < typename T >
788 inline
790 {
791  return d->header;
792 }
793 
794 
795 template<typename T>
796 inline
798 {
799  if( hdr != d->header )
800  {
801  aims::PythonHeader *mh;
802  if( !d->header )
803  {
804  d->header = mh = new aims::PythonHeader( *_volume );
805  }
806  else
807  {
808  mh = static_cast<aims::PythonHeader *>( d->header );
809  carto::Object oldvs;
810  try
811  {
812  // retreive old voxel size (if any)
813  oldvs = mh->getProperty( "voxel_size" );
814  }
815  catch( ... )
816  {
817  }
818  mh->clearProperties();
819  if( !oldvs.isNull() )
820  /* keep old voxel size which was not part of the dynamic header
821  in the old AimsData */
822  mh->setProperty( "voxel_size", oldvs );
823  }
824  const aims::PythonHeader
825  *ph = dynamic_cast<const aims::PythonHeader *>( hdr );
826  if( ph )
827  mh->copy( *ph );
828  // hdr used to transfor ownership to me
829  delete hdr;
830  }
831 }
832 
833 
834 template < typename T >
835 inline
836 typename AimsData<T>::reference
838 {
839  return *( begin() + n );
840 }
841 
842 
843 template < typename T >
844 inline
847 {
848  return *( begin() + n );
849 }
850 
851 
852 template < typename T >
853 inline
854 typename AimsData<T>::reference
857 {
858  return (*_volume)( x, y, z, t );
859 }
860 
861 
862 template < typename T >
863 inline
867  AimsData<T>::size_type t ) const
868 {
869  return (*_volume)( x, y, z, t );
870 }
871 
872 
873 template < typename T >
874 inline
875 typename AimsData<T>::reference
877 {
878  return (*this)( pt[0], pt[1], pt[2], pt[3] );
879 }
880 
881 
882 template < typename T >
883 inline
886 {
887  return (*this)( pt[0], pt[1], pt[2], pt[3] );
888 }
889 
890 
891 template < typename T >
892 inline
893 typename AimsData<T>::reference
895 {
896  return (*this)( pt[0], pt[1], pt[2], pt[3] );
897 }
898 
899 
900 template < typename T >
901 inline
904 {
905  return (*this)( pt[0], pt[1], pt[2], pt[3] );
906 }
907 
908 
909 template < typename T >
910 inline
911 typename AimsData<T>::reference
913 {
914  return (*this)( pt[0], pt[1], pt[2] );
915 }
916 
917 
918 template < typename T >
919 inline
922 {
923  return (*this)( pt[0], pt[1], pt[2] );
924 }
925 
926 
927 template < typename T >
928 inline
929 typename AimsData<T>::reference
931 {
932  return (*this)( pt[0], pt[1], pt[2] );
933 }
934 
935 
936 template < typename T >
937 inline
940 {
941  return (*this)( pt[0], pt[1], pt[2] );
942 }
943 
944 
945 template < typename T >
946 inline
947 typename AimsData<T>::reference
949 {
950  return (*this)( pt[0], pt[1] );
951 }
952 
953 
954 template < typename T >
955 inline
958 {
959  return (*this)( pt[0], pt[1] );
960 }
961 
962 
963 template < typename T >
964 inline
965 typename AimsData<T>::reference
967 {
968  return (*this)( pt[0], pt[1] );
969 }
970 
971 
972 template < typename T >
973 inline
976 {
977  return (*this)( pt[0], pt[1] );
978 }
979 
980 
981 template < typename T >
982 inline
984 {
985  T mini;
986  const_iterator it = begin() + oFirstPoint();
987 
988  mini = *it;
989  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
990 
991  for ( t = 0; t < tm; t++ )
992  {
993  for ( z = 0; z < zm; z++ )
994  {
995  for ( y = 0; y < ym; y++ )
996  {
997  for ( x = 0; x < xm; x++ )
998  {
999  if ( *it < mini )
1000  mini = *it;
1001  it++;
1002  }
1003  it += oPointBetweenLine();
1004  }
1005  it += oLineBetweenSlice();
1006  }
1007  it += oSliceBetweenVolume();
1008  }
1009 
1010  return mini;
1011 }
1012 
1013 
1014 template < typename T >
1015 inline
1017 {
1018  T maxi;
1019  const_iterator it = begin() + oFirstPoint();
1020 
1021  maxi = *it;
1022  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1023 
1024  for ( t = 0; t < tm; t++ )
1025  {
1026  for ( z = 0; z < zm; z++ )
1027  {
1028  for ( y = 0; y < ym; y++ )
1029  {
1030  for ( x = 0; x < xm; x++ )
1031  {
1032  if ( *it > maxi )
1033  maxi = *it;
1034  it++;
1035  }
1036  it += oPointBetweenLine();
1037  }
1038  it += oLineBetweenSlice();
1039  }
1040  it += oSliceBetweenVolume();
1041  }
1042 
1043  return maxi;
1044 }
1045 
1046 
1047 template < typename T >
1048 inline
1049 T AimsData<T>::minIndex( int* xx, int* yy, int* zz, int* tt ) const
1050 {
1051  int minxind = 0,minyind = 0,minzind = 0,mintind = 0;
1052  T mini;
1053  const_iterator it = begin() + oFirstPoint();
1054 
1055  mini = *it;
1056  int x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1057 
1058  for ( t = 0; t < tm; t++ )
1059  {
1060  for ( z = 0; z < zm; z++ )
1061  {
1062  for ( y = 0; y < ym; y++ )
1063  {
1064  for ( x = 0; x < xm; x++ )
1065  {
1066  if ( *it < mini )
1067  {
1068  mini = *it;
1069  minxind = x;
1070  minyind = y;
1071  minzind = z;
1072  mintind = t;
1073  }
1074  it++;
1075  }
1076  it += oPointBetweenLine();
1077  }
1078  it += oLineBetweenSlice();
1079  }
1080  it += oSliceBetweenVolume();
1081  }
1082  if ( xx )
1083  *xx = minxind;
1084  if ( yy )
1085  *yy = minyind;
1086  if ( zz )
1087  *zz = minzind;
1088  if ( tt )
1089  *tt = mintind;
1090 
1091  return mini;
1092 }
1093 
1094 
1095 template < typename T >
1096 inline
1097 T AimsData<T>::maxIndex( int* xx, int* yy, int* zz, int* tt ) const
1098 {
1099  int maxxind = 0,maxyind = 0,maxzind = 0,maxtind = 0;
1100  T maxi;
1101  const_iterator it = begin() + oFirstPoint();
1102 
1103  maxi = *it;
1104  int x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1105 
1106  for ( t = 0; t < tm; t++ )
1107  {
1108  for ( z = 0; z < zm; z++ )
1109  {
1110  for ( y = 0; y < ym; y++ )
1111  {
1112  for ( x = 0; x < xm; x++ )
1113  {
1114  if ( *it > maxi )
1115  {
1116  maxi = *it;
1117  maxxind = x;
1118  maxyind = y;
1119  maxzind = z;
1120  maxtind = t;
1121  }
1122  it++;
1123  }
1124  it += oPointBetweenLine();
1125  }
1126  it += oLineBetweenSlice();
1127  }
1128  it += oSliceBetweenVolume();
1129  }
1130  if ( xx )
1131  *xx = maxxind;
1132  if ( yy )
1133  *yy = maxyind;
1134  if ( zz )
1135  *zz = maxzind;
1136  if ( tt )
1137  *tt = maxtind;
1138 
1139  return maxi;
1140 }
1141 
1142 
1143 template < typename T >
1144 inline
1145 void AimsData<T>::fillBorder( const T& val )
1146 {
1147  carto::VolumeRef<T> bigger = _volume->refVolume();
1148  if( bigger.isNull() )
1149  return;
1150  T *it;
1151  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1152  long of = &_volume->at( 0, 0, 0, 0 ) - &bigger->at( 0, 0, 0, 0 ),
1153  op = &_volume->at( 0, 1, 0, 0 ) - &_volume->at( xm, 0, 0, 0 ),
1154  ol = &_volume->at( 0, 0, 1, 0 ) - &_volume->at( 0, ym, 0, 0 );
1155 
1156  for ( t = 0; t < tm; t++ )
1157  {
1158  it = &bigger->at( 0, 0, 0, t );
1159  for ( x = 0; x < of; x++ )
1160  *it++ = val;
1161  for ( z = 0; z < zm; z++ )
1162  {
1163  for ( y = 0; y < ym; y++ )
1164  {
1165  it += xm;
1166  for ( x = 0; x < op; x++ )
1167  *it++ = val;
1168  }
1169  for ( x = 0; x < ol; x++ )
1170  *it++ = val;
1171  }
1172  for ( x = 0; x < of - op - ol; x++ )
1173  *it++ = val;
1174  }
1175 }
1176 
1177 
1178 template<typename T>
1180 {
1181  AimsData<T> dat( *this );
1182  if( !_volume->refVolume().isNull() )
1183  {
1184  // border has to be copied
1186  new carto::Volume<T>( *_volume->refVolume() ) );
1187  dat._volume.reset( new carto::Volume<T>( rvol, _volume->posInRefVolume(),
1188  typename carto::Volume<T>::Position4Di( _volume->getSizeX(),
1189  _volume->getSizeY(),
1190  _volume->getSizeZ(),
1191  _volume->getSizeT() ) ) );
1192  dat._volume->header().copyProperties(
1193  carto::Object::reference( _volume->header() ) );
1194  }
1195  else
1196  dat._volume.reset( new carto::Volume<T>( *_volume ) );
1197  delete dat.d->header;
1198  dat.d->header = new aims::PythonHeader( *dat._volume );
1199  return dat;
1200 }
1201 
1202 
1203 template < typename T >
1204 inline
1206 {
1207  ASSERT( dimT() == 1 && other.dimT() == 1 &&
1208  dimZ() == 1 && other.dimZ() == 1 );
1209  ASSERT( dimY() == other.dimX() );
1210 
1211  AimsData<T> prod( dimX(), other.dimY(), 1, 1,
1212  std::max( borderWidth(), other.borderWidth() ) );
1213  for ( long y = 0; y < other.dimY(); y++ )
1214  for ( long x = 0; x < dimX(); x++ )
1215  {
1216  prod( x, y ) = T( 0 );
1217  for ( long k = 0; k < dimY(); k++ )
1218  prod( x, y ) += (*this)( x, k ) * other( k, y );
1219  }
1220 
1221  return prod;
1222 }
1223 
1224 
1225 template < typename T >
1226 inline
1228 {
1229  AimsData<T> tmp( dimY(), dimX(), dimZ(), dimT(), borderWidth() );
1231  *ph = dynamic_cast<aims::PythonHeader *>( header() );
1232  if( ph )
1233  {
1234  ph = static_cast<aims::PythonHeader *>( ph->cloneHeader() );
1235  if( ph->hasProperty( "volume_dimension" ) )
1236  ph->removeProperty( "volume_dimension" );
1237  if( ph->hasProperty( "voxel_size" ) )
1238  ph->removeProperty( "voxel_size" );
1239  tmp.setHeader( ph );
1240  }
1241  tmp.setSizeXYZT( sizeY(), sizeX(), sizeZ(), sizeT() );
1242  tmp.fillBorder( T( 0 ) );
1243 
1244  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1245 
1246  for ( t = 0; t < tm; t++ )
1247  for ( z = 0; z < zm; z++ )
1248  for ( y = 0; y < ym; y++ )
1249  for ( x = 0; x < xm; x++ )
1250  tmp( y, x, z, t ) = (*this)( x, y, z, t );
1251 
1252  *this = tmp;
1253  return *this;
1254 }
1255 
1256 
1257 template < typename T >
1258 inline
1260  const AimsData<T>& secondThing )
1261 {
1262  carto::VolumeRef<T> v = carto::VolumeRef<T>(firstThing.volume()).deepcopy();
1263  v += carto::VolumeRef<T>(secondThing.volume());
1264  return v;
1265 }
1266 
1267 
1268 template < typename T >
1269 inline
1271  const AimsData<T>& secondThing )
1272 {
1273  carto::VolumeRef<T> v = carto::VolumeRef<T>(firstThing.volume()).deepcopy();
1274  v -= carto::VolumeRef<T>(secondThing.volume());
1275  return v;
1276 }
1277 
1278 template < typename T >
1279 inline
1280 AimsData<T> operator * ( const AimsData<T>& firstThing, float scale )
1281 {
1282  carto::VolumeRef<T> v = carto::VolumeRef<T>(firstThing.volume()).deepcopy();
1283  v *= scale;
1284  return v;
1285 }
1286 
1287 
1288 // macros
1289 
1290 #define ForEach4d( thing , x , y , z , t) \
1291  for ( t = 0; t < thing.dimT(); t++ ) \
1292  for ( z = 0; z < thing.dimZ(); z++ ) \
1293  for ( y = 0; y < thing.dimY(); y++ ) \
1294  for ( x = 0; x < thing.dimX(); x++ )
1295 
1296 #define ForEach3d( thing , x , y , z) \
1297  for ( z = 0; z < thing.dimZ(); z++ ) \
1298  for ( y = 0; y < thing.dimY(); y++ ) \
1299  for ( x = 0; x < thing.dimX(); x++ )
1300 
1301 #define ForEach2d( thing , x , y) \
1302  for ( y = 0; y < thing.dimY(); y++ ) \
1303  for ( x = 0; x < thing.dimX(); x++ )
1304 
1305 #define ForEach1d( thing , x) \
1306  for ( x = 0; x < thing.dimX(); x++ )
1307 
1308 
1309 #define ForEach4dp( thing , x , y , z , t) \
1310  for ( t = 0; t < thing->dimT(); t++ ) \
1311  for ( z = 0; z < thing->dimZ(); z++ ) \
1312  for ( y = 0; y < thing->dimY(); y++ ) \
1313  for ( x = 0; x < thing->dimX(); x++ )
1314 
1315 #define ForEach3dp( thing , x , y , z) \
1316  for ( z = 0; z < thing->dimZ(); z++ ) \
1317  for ( y = 0; y < thing->dimY(); y++ ) \
1318  for ( x = 0; x < thing->dimX(); x++ )
1319 
1320 #define ForEach2dp( thing , x , y) \
1321  for ( y = 0; y < thing->dimY(); y++ ) \
1322  for ( x = 0; x < thing->dimX(); x++ )
1323 
1324 #define ForEach1dp( thing , x) \
1325  for ( x = 0; x < thing->dimX(); x++ )
1326 
1327 
1328 class DtiTensor;
1329 
1330 namespace carto
1331 {
1332  // instanciations of Volume classes
1333 
1334  extern template class VolumeProxy<AimsRGB>;
1335  extern template class Volume<AimsRGB>;
1336  extern template class VolumeProxy<AimsRGBA>;
1337  extern template class Volume<AimsRGBA>;
1338  extern template class VolumeProxy<Point3d>;
1339  extern template class Volume<Point3d>;
1340  extern template class VolumeProxy<Point3df>;
1341  extern template class Volume<Point3df>;
1342  extern template class VolumeProxy<Point2d>;
1343  extern template class Volume<Point2d>;
1344  extern template class VolumeProxy<AimsVector<float,6> >;
1345  extern template class Volume<AimsVector<float,6> >;
1346  extern template class VolumeProxy<DtiTensor*>;
1347  extern template class Volume<DtiTensor*>;
1348 
1349  // VolumeUtil declarations (needed on Mac)
1350  extern template VolumeRef<AimsRGB>
1351  VolumeUtil<AimsRGB>::apply( Scaler<AimsRGB, double>,
1352  const VolumeRef<AimsRGB> & );
1353  extern template void
1354  VolumeUtil<AimsRGB>::selfApply( Scaler<AimsRGB, double>,
1355  VolumeRef<AimsRGB> & );
1356  extern template VolumeRef<AimsRGB>
1357  VolumeUtil<AimsRGB>::apply( std::plus<AimsRGB>, const VolumeRef<AimsRGB> &,
1358  const VolumeRef<AimsRGB> & );
1359  extern template void
1360  VolumeUtil<AimsRGB>::selfApply( std::plus<AimsRGB>, VolumeRef<AimsRGB> &,
1361  const VolumeRef<AimsRGB> & );
1362  extern template VolumeRef<AimsRGB>
1363  VolumeUtil<AimsRGB>::apply( UnaryFromConstantBinaryFunctor<AimsRGB,
1364  std::plus<AimsRGB> >,
1365  const VolumeRef<AimsRGB> & );
1366  extern template void
1367  VolumeUtil<AimsRGB>::selfApply( UnaryFromConstantBinaryFunctor<AimsRGB,
1368  std::plus<AimsRGB> >, VolumeRef<AimsRGB> & );
1369  extern template VolumeRef<AimsRGB>
1370  VolumeUtil<AimsRGB>::apply( UnaryFromConstantBinaryFunctor2<AimsRGB,
1371  std::plus<AimsRGB> >,
1372  const VolumeRef<AimsRGB> & );
1373  extern template VolumeRef<AimsRGB>
1374  VolumeUtil<AimsRGB>::apply( std::minus<AimsRGB>, const VolumeRef<AimsRGB> &,
1375  const VolumeRef<AimsRGB> & );
1376  extern template void
1377  VolumeUtil<AimsRGB>::selfApply( std::minus<AimsRGB>, VolumeRef<AimsRGB> &,
1378  const VolumeRef<AimsRGB> & );
1379  extern template VolumeRef<AimsRGB>
1380  VolumeUtil<AimsRGB>::apply( UnaryFromConstantBinaryFunctor<AimsRGB,
1381  std::minus<AimsRGB> >,
1382  const VolumeRef<AimsRGB> & );
1383  extern template void
1384  VolumeUtil<AimsRGB>::selfApply( UnaryFromConstantBinaryFunctor<AimsRGB,
1385  std::minus<AimsRGB> >,
1386  VolumeRef<AimsRGB> & );
1387  extern template VolumeRef<AimsRGB>
1388  VolumeUtil<AimsRGB>::apply( UnaryFromConstantBinaryFunctor2<AimsRGB,
1389  std::minus<AimsRGB> >,
1390  const VolumeRef<AimsRGB> & );
1391 
1392  extern template VolumeRef<AimsRGBA>
1393  VolumeUtil<AimsRGBA>::apply( Scaler<AimsRGBA, double>,
1394  const VolumeRef<AimsRGBA> & );
1395  extern template void
1396  VolumeUtil<AimsRGBA>::selfApply( Scaler<AimsRGBA, double>,
1397  VolumeRef<AimsRGBA> & );
1398  extern template VolumeRef<AimsRGBA>
1399  VolumeUtil<AimsRGBA>::apply( std::plus<AimsRGBA>,
1400  const VolumeRef<AimsRGBA> &,
1401  const VolumeRef<AimsRGBA> & );
1402  extern template void
1403  VolumeUtil<AimsRGBA>::selfApply( std::plus<AimsRGBA>, VolumeRef<AimsRGBA> &,
1404  const VolumeRef<AimsRGBA> & );
1405  extern template VolumeRef<AimsRGBA>
1406  VolumeUtil<AimsRGBA>::apply( UnaryFromConstantBinaryFunctor<AimsRGBA,
1407  std::plus<AimsRGBA> >,
1408  const VolumeRef<AimsRGBA> & );
1409  extern template void
1410  VolumeUtil<AimsRGBA>::selfApply( UnaryFromConstantBinaryFunctor<AimsRGBA,
1411  std::plus<AimsRGBA> >,
1412  VolumeRef<AimsRGBA> & );
1413  extern template VolumeRef<AimsRGBA>
1414  VolumeUtil<AimsRGBA>::apply( UnaryFromConstantBinaryFunctor2<AimsRGBA,
1415  std::plus<AimsRGBA> >,
1416  const VolumeRef<AimsRGBA> & );
1417  extern template VolumeRef<AimsRGBA>
1418  VolumeUtil<AimsRGBA>::apply( std::minus<AimsRGBA>,
1419  const VolumeRef<AimsRGBA> &,
1420  const VolumeRef<AimsRGBA> & );
1421  extern template void
1422  VolumeUtil<AimsRGBA>::selfApply( std::minus<AimsRGBA>,
1423  VolumeRef<AimsRGBA> &,
1424  const VolumeRef<AimsRGBA> & );
1425  extern template VolumeRef<AimsRGBA>
1426  VolumeUtil<AimsRGBA>::apply( UnaryFromConstantBinaryFunctor<AimsRGBA,
1427  std::minus<AimsRGBA> >,
1428  const VolumeRef<AimsRGBA> & );
1429  extern template void
1430  VolumeUtil<AimsRGBA>::selfApply( UnaryFromConstantBinaryFunctor<AimsRGBA,
1431  std::minus<AimsRGBA> >,
1432  VolumeRef<AimsRGBA> & );
1433  extern template VolumeRef<AimsRGBA>
1434  VolumeUtil<AimsRGBA>::apply( UnaryFromConstantBinaryFunctor2<AimsRGBA,
1435  std::minus<AimsRGBA> >,
1436  const VolumeRef<AimsRGBA> & );
1437 }
1438 
1439 
1440 #endif
1441 
virtual void setArrayItem(int, Object)=0
void setSizeT(float sizet)
T & reference
basic reference
std::string dataType()
reference operator()(size_type x=0, size_type y=0, size_type z=0, size_type t=0)
T minimum() const
AimsData< T > & transpose()
const T * const_iterator
basic constant iterator
T **** pointer4d
4D-pointer
AimsData(int dimx=1, int dimy=1, int dimz=1, int dimt=1, int borderw=0)
Attributed python-like header, stores all needed information about an object, currently used for volu...
Definition: pheader.h:51
virtual Object getArrayItem(int index) const =0
iterator begin()
int dimX() const
static VolumeRef< T > apply(UnaryFunction f, const VolumeRef< T > &o)
float sizeY() const
virtual bool hasProperty(const std::string &) const
iterator begin()
int getSizeT() const
static int borderWidth(carto::rc_ptr< carto::Volume< T > > vol)
T * iterator
basic iterator
bool isNull() const
The template class to implement basic vectors.
Definition: vector.h:48
The base class to manage borders on data containers.
Definition: border.h:47
ptrdiff_t difference_type
difference type
int dimT() const
virtual void copy(const PythonHeader &, bool keepUuid=false)
const T & at(long x, long y=0, long z=0, long t=0) const
size_t size_type
size of the basic type
AimsData< T > operator+(const AimsData< T > &firstThing, const AimsData< T > &secondThing)
AimsData< T > operator-(const AimsData< T > &firstThing, const AimsData< T > &secondThing)
static Object reference(T &value)
std::string name()
virtual Header * cloneHeader(bool keepUuid=false) const
void setSizeX(float sizex)
virtual bool removeProperty(const std::string &)
void setSizeY(float sizey)
void setHeader(aims::Header *hdr)
T maximum() const
T maxIndex(int *x, int *y, int *z, int *t) const
virtual double getScalar() const =0
int borderWidth() const
Usefull offsets for A.I.M.S.
Definition: border.h:135
carto::Object getObjectHeader(Headered &h)
T * get() const
void fillBorder(const T &val)
const carto::AllocatorContext & allocator() const
virtual ~AimsData()
virtual void clearProperties()
T * pointer
basic pointer
bool empty() const
AimsData< T > & operator=(carto::rc_ptr< carto::Volume< T > > vol)
virtual Object objectIterator() const =0
int getSizeZ() const
AimsData< T > clone() const
AimsData< T > operator*(const AimsData< T > &firstThing, float scale)
AimsData< T > cross(const AimsData< T > &other)
float sizeT() const
int getSizeX() const
rc_ptr< Volume< T > > refVolume() const
Border(int dimx, int dimy, int dimz, int width=0)
The constructor precalculates offsets to speed-up access to data during loops.
Definition: border.h:122
float sizeZ() const
static Object value()
carto::rc_ptr< carto::Volume< T > > volume()
virtual bool getProperty(const std::string &, Object &) const
virtual Object currentValue() const =0
float sizeX() const
int dimZ() const
virtual void setProperty(const std::string &, Object)
void setSizeXYZT(float sizex=1.0f, float sizey=1.0f, float sizez=1.0f, float sizet=1.0f)
int dimY() const
const T & const_reference
basic constant reference
iterator end()
void reset(T *p=NULL)
virtual size_t size() const =0
T minIndex(int *x, int *y, int *z, int *t) const
#define ASSERT(EX)
static void selfApply(UnaryFunction f, VolumeRef< T > &o)
void setSizeZ(float sizez)
const aims::Header * header() const
aims::Header * header
virtual bool isValid() const =0
reference operator[](size_type n)
int getSizeY() const