aimsdata  5.0.5
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/border/border.h>
41 #include <aims/rgb/rgb.h>
42 #include <cartobase/smart/rcptr.h>
44 #include <aims/data/pheader.h>
45 
46 #include <algorithm>
47 
48 
49 template<typename T>
50 class AimsData : public carto::RCObject, public aims::Border
51 {
52  public:
53  typedef T value_type;
55  typedef T* pointer;
57  typedef T**** pointer4d;
59  typedef T* iterator;
61  typedef const T* const_iterator;
63  typedef T& reference;
65  typedef const T& const_reference;
67  typedef size_t size_type;
69  typedef ptrdiff_t difference_type;
70 
71  iterator begin();
72  const_iterator begin() const;
73  iterator end();
74  const_iterator end() const;
75  bool empty() const;
76 
77  AimsData( int dimx = 1, int dimy = 1, int dimz = 1, int dimt = 1,
78  int borderw = 0 );
79  AimsData( int dimx, int dimy, int dimz, int dimt,
80  int borderw, const carto::AllocatorContext & al );
81  AimsData( const AimsData<T>& other );
82  AimsData( const AimsData<T>& other, int borderw );
83  virtual ~AimsData();
84 
85  // conversions with carto::Volume
88 
89  AimsData<T> & operator = ( const AimsData<T> & );
90  AimsData<T> & operator = ( const T & );
91 
95  operator carto::rc_ptr<carto::Volume<T> >();
96  operator const carto::rc_ptr<carto::Volume<T> >() const;
97 
98  const carto::AllocatorContext & allocator() const;
99  int dimX() const;
100  int dimY() const;
101  int dimZ() const;
102  int dimT() const;
103  float sizeX() const;
104  float sizeY() const;
105  float sizeZ() const;
106  float sizeT() const;
107  void setSizeX( float sizex );
108  void setSizeY( float sizey );
109  void setSizeZ( float sizez );
110  void setSizeT( float sizet );
111  void setSizeXYZT( float sizex = 1.0f, float sizey = 1.0f,
112  float sizez = 1.0f, float sizet = 1.0f );
113  void setSizeXYZT( const AimsData<T>& other );
114  const aims::Header* header() const;
115  aims::Header* header();
116  void setHeader( aims::Header* hdr );
117  reference operator [] ( size_type n );
118  const_reference operator [] ( size_type n ) const;
119  reference operator () ( size_type x = 0, size_type y = 0,
120  size_type z = 0, size_type t = 0 );
121  const_reference operator () ( size_type x = 0, size_type y = 0,
122  size_type z = 0, size_type t = 0 ) const;
123  reference operator () ( const Point4d& pt );
124  const_reference operator () ( const Point4d& pt ) const;
125  reference operator () ( const Point4dl& pt );
126  const_reference operator () ( const Point4dl& pt ) const;
127  reference operator () ( const Point3d& pt );
128  const_reference operator () ( const Point3d& pt ) const;
129  reference operator () ( const Point3dl& pt );
130  const_reference operator () ( const Point3dl& pt ) const;
131  reference operator () ( const Point2d& pt );
132  const_reference operator () ( const Point2d& pt ) const;
133  reference operator () ( const Point2dl& pt );
134  const_reference operator () ( const Point2dl& pt ) const;
135 
136  T minimum() const;
137  T maximum() const;
138  T minIndex( int* x, int* y, int* z, int* t ) const;
139  T maxIndex( int* x, int* y, int* z, int* t ) const;
140  void fillBorder( const T& val );
141  AimsData<T> clone () const;
142  AimsData<T> cross( const AimsData<T>& other );
144 
145  private:
146  void initBorder();
147  struct Private;
148 
150  Private *d;
151 };
152 
153 
154 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
155 
156 namespace carto
157 {
158 
159  template<class T> class DataTypeCode<AimsData<T> >
160  {
161  public:
162  static std::string objectType()
163  { return "Volume"; }
164  static std::string dataType()
165  { return DataTypeCode<T>::dataType(); }
166  static std::string name()
167  {
168  return std::string("volume of ") + DataTypeCode< T >::name();
169  }
170  };
171 
172  template <typename T>
174  {
175  return carto::Object::reference( obj.volume()->header() );
176  }
177 
178 }
179 
180 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES
181 
182 // private struct
183 
184 template<typename T>
185 struct AimsData<T>::Private
186 {
187  Private();
188  ~Private();
189 
190  static int borderWidth( carto::rc_ptr<carto::Volume<T> > vol );
191 
193 };
194 
195 
196 // inline methods definition
197 
198 // Private struct methods
199 
200 template<typename T>
201 inline
203  : header( 0 )
204 {
205 }
206 
207 
208 template<typename T>
209 inline
211 {
212  if( header )
213  delete header;
214 }
215 
216 
217 template<typename T>
218 inline
220 {
221  if( !vol->refVolume().isNull() ) // is a view to another volume
222  if (vol->refVolume()->allocatorContext().isAllocated()) {
223  // AimsData is not able to deal with different border sizes, so we get the
224  // minimum border through dimensions
225  const std::vector<int> vborders = vol->getBorders();
226 
227  // Borders are not defined for T dimension so we must only deal with
228  // X, Y and Z dimensions
229  std::vector<int>::const_iterator vbordersend = (vborders.size() > 6
230  ? vborders.begin() + 6
231  : vborders.end());
232  if(vborders.begin() != vbordersend) {
233  std::vector<int>::const_iterator minit = std::min_element(vborders.begin(),
234  vbordersend);
235  return (minit == vbordersend ? 0 : *minit);
236  }
237  }
238  return 0;
239 }
240 
241 
242 // AimsData methods
243 
244 template <typename T>
246 {
247  return volume();
248 }
249 
250 
251 template <typename T>
253 {
254  return volume();
255 }
256 
257 
258 template<typename T>
259 inline
261 {
262  return &*_volume->begin();
263 }
264 
265 
266 template<typename T>
267 inline
269 {
270  return &*_volume->begin();
271 }
272 
273 
274 template<typename T>
275 inline
277 {
278  // &*_volume->end() may return 0 with some versions of blitz++
279  // do does not make a valid pointer for end
280  return &_volume->at( _volume->getSizeX() - 1, _volume->getSizeY() - 1,
281  _volume->getSizeZ() - 1, _volume->getSizeT() - 1 ) + 1;
282 }
283 
284 
285 template<typename T>
286 inline
288 {
289  // &*_volume->end() may return 0 with some versions of blitz++
290  // do does not make a valid pointer for end
291  return &_volume->at( _volume->getSizeX() - 1, _volume->getSizeY() - 1,
292  _volume->getSizeZ() - 1, _volume->getSizeT() - 1 ) + 1;
293 }
294 
295 
296 template<typename T>
297 inline
298 bool AimsData<T>::empty() const
299 {
300  return _volume->begin() == _volume->end();
301 }
302 
303 template<typename T>
304 inline
306 {
307  _oFirstPoint = 0;
308  _oLine = &_volume->at( 0, 1 ) - &_volume->at( 0 );
309  _oPointBetweenLine = &_volume->at( 0, 1 ) - &_volume->at( dimX() );
310  _oSlice = &_volume->at( 0, 0, 1 ) - &_volume->at( 0 );
311  _oLineBetweenSlice = &_volume->at( 0, 0, 1 ) - &_volume->at( 0, dimY() );
312  _oVolume = &_volume->at( 0, 0, 0, 1 ) - &_volume->at( 0 );
313  _oSliceBetweenVolume = &_volume->at( 0, 0, 0, 1 )
314  - &_volume->at( 0, 0, dimZ() );
315 }
316 
317 
318 template<typename T>
319 inline
320 AimsData<T>::AimsData( int dimx, int dimy, int dimz, int dimt, int borderw )
321  : carto::RCObject(), aims::Border( dimx, dimy, dimz, borderw ),
322  _volume( new carto::Volume<T>( dimx + borderw * 2, dimy + borderw * 2,
323  dimz + borderw * 2, dimt ) ),
324  d( new Private )
325 {
326  if( borderw != 0 )
327  _volume.reset( new carto::Volume<T>(
328  _volume,
329  typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
330  typename carto::Volume<T>::Position4Di( dimx, dimy, dimz, dimt ) ) );
331  d->header = new aims::PythonHeader( *_volume );
332  initBorder();
333 }
334 
335 
336 template < typename T >
337 inline
338 AimsData<T>::AimsData( int dimx, int dimy, int dimz, int dimt,
339  int borderw, const carto::AllocatorContext & al )
340  : carto::RCObject(), aims::Border( dimx, dimy, dimz, borderw ),
341  _volume( new carto::Volume<T>( dimx + borderw * 2, dimy + borderw * 2,
342  dimz + borderw * 2, dimt, al ) ),
343  d( new Private )
344 {
345  if( borderw != 0 )
346  _volume.reset( new carto::Volume<T>(
347  _volume,
348  typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
349  typename carto::Volume<T>::Position4Di( dimx, dimy, dimz, dimt ), al ) );
350  d->header = new aims::PythonHeader( *_volume );
351  initBorder();
352 }
353 
354 
355 template < typename T >
356 inline
358  : carto::RCObject(), aims::Border( other.dimX(), other.dimY(),
359  other.dimZ(), other.borders() ),
360  _volume( other._volume ),
361  d( new Private )
362 {
363  d->header = new aims::PythonHeader( *_volume );
364  initBorder();
365 }
366 
367 
368 template < typename T >
369 inline
370 AimsData<T>::AimsData( const AimsData<T>& other, int borderw )
371  : carto::RCObject(), aims::Border( other.dimX(), other.dimY(), other.dimZ(),
372  borderw ), _volume( new carto::Volume<T>( other.dimX() + borderw * 2,
373  other.dimY() + borderw * 2, other.dimZ() + borderw * 2, other.dimT() ) ),
374  d( new Private )
375 {
376  _volume->copyHeaderFrom( other.volume()->header() );
377 
378  if( borderw != 0 )
379  _volume.reset( new carto::Volume<T>(
380  _volume,
381  typename carto::Volume<T>::Position4Di( borderw, borderw, borderw, 0 ),
382  typename carto::Volume<T>::Position4Di( other.dimX(), other.dimY(),
383  other.dimZ(), other.dimT() ) ) );
384 
385  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
386  for ( t = 0; t < tm; t++ )
387  for ( z = 0; z < zm; z++ )
388  for ( y = 0; y < ym; y++ )
389  for ( x = 0; x < xm; x++ )
390  (*this)( x, y, z, t ) = other( x, y, z, t );
391  d->header = new aims::PythonHeader( *_volume );
392 
393  initBorder();
394 }
395 
396 
397 template < typename T >
398 inline
400 {
401  delete d;
402 }
403 
404 
405 template < typename T >
406 inline
408  : carto::RCObject(),
409  aims::Border( vol->getSizeX(),
410  vol->getSizeY(),
411  vol->getSizeZ(),
412  vol->getBorders() ),
413  _volume( vol ),
414  d( new Private )
415 {
416  d->header = new aims::PythonHeader( *_volume );
417  initBorder();
418 }
419 
420 
421 template < typename T >
422 inline
424 {
425  if( _volume.get() == vol.get() )
426  return *this;
427 
428  _setBorder( vol->getSizeX(), vol->getSizeY(), vol->getSizeZ(),
429  vol->getBorders() );
430  delete d->header;
431  _volume = vol;
432  d->header = new aims::PythonHeader( *_volume );
433  initBorder();
434 
435  return *this;
436 }
437 
438 
439 template < typename T >
440 inline
442 {
443  if ( &other == this )
444  return *this;
445 
446  _setBorder( other.dimX(), other.dimY(), other.dimZ(),
447  other.borders() );
448  delete d->header;
449  _volume = other._volume;
450  *d = *other.d;
451  d->header = new aims::PythonHeader( *_volume );
452  initBorder();
453  return *this;
454 }
455 
456 
457 template < typename T >
458 inline
460 {
461  iterator it = begin() + oFirstPoint();
462  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
463 
464  for ( t = 0; t < tm; t++ )
465  {
466  for ( z = 0; z < zm; z++ )
467  {
468  for ( y = 0; y < ym; y++ )
469  {
470  for ( x = 0; x < xm; x++ )
471  *it++ = val;
472  it += oPointBetweenLine();
473  }
474  it += oLineBetweenSlice();
475  }
476  it += oSliceBetweenVolume();
477  }
478  return *this;
479 }
480 
481 
482 template<typename T>
483 inline
485 {
486  return _volume;
487 }
488 
489 
490 template<typename T>
491 inline
493 {
494  return _volume;
495 }
496 
497 
498 template<typename T>
499 inline
500 int AimsData<T>::dimX() const
501 {
502  return _volume->getSizeX();
503 }
504 
505 
506 template<typename T>
507 inline
508 int AimsData<T>::dimY() const
509 {
510  return _volume->getSizeY();
511 }
512 
513 
514 template<typename T>
515 inline
516 int AimsData<T>::dimZ() const
517 {
518  return _volume->getSizeZ();
519 }
520 
521 
522 template<typename T>
523 inline
524 int AimsData<T>::dimT() const
525 {
526  return _volume->getSizeT();
527 }
528 
529 
530 template < typename T >
531 inline
532 float AimsData<T>::sizeX() const
533 {
534  if( !d->header )
535  return 1;
536  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
537  if( !ph )
538  return 1;
539  try
540  {
541  carto::Object vs = ph->getProperty( "voxel_size" );
542  if( !vs.isNull() && vs->size() >= 1 )
543  return (float) vs->getArrayItem( 0 )->getScalar();
544  }
545  catch( ... )
546  {
547  }
548  return 1;
549 }
550 
551 
552 template < typename T >
553 inline
554 float AimsData<T>::sizeY() const
555 {
556  if( !d->header )
557  return 1;
558  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
559  if( !ph )
560  return 1;
561  try
562  {
563  carto::Object vs = ph->getProperty( "voxel_size" );
564  if( !vs.isNull() && vs->size() >= 2 )
565  return (float) vs->getArrayItem( 1 )->getScalar();
566  }
567  catch( ... )
568  {
569  }
570  return 1;
571 }
572 
573 
574 template < typename T >
575 inline
576 float AimsData<T>::sizeZ() const
577 {
578  if( !d->header )
579  return 1;
580  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
581  if( !ph )
582  return 1;
583  try
584  {
585  carto::Object vs = ph->getProperty( "voxel_size" );
586  if( !vs.isNull() && vs->size() >= 3 )
587  return (float) vs->getArrayItem( 2 )->getScalar();
588  }
589  catch( ... )
590  {
591  }
592  return 1;
593 }
594 
595 
596 template < typename T >
597 inline
598 float AimsData<T>::sizeT() const
599 {
600  if( !d->header )
601  return 1;
602  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
603  if( !ph )
604  return 1;
605  try
606  {
607  carto::Object vs = ph->getProperty( "voxel_size" );
608  if( !vs.isNull() && vs->size() >= 4 )
609  return (float) vs->getArrayItem( 3 )->getScalar();
610  }
611  catch( ... )
612  {
613  }
614  return 1;
615 }
616 
617 
618 template < typename T >
619 inline
620 void AimsData<T>::setSizeX( float sizex )
621 {
622  if( !d->header )
624  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
625  if( ph )
626  {
627  try
628  {
629  carto::Object vs = ph->getProperty( "voxel_size" );
630  if( !vs.isNull() )
631  if( vs->size() >= 1 )
632  vs->setArrayItem( 0, carto::Object::value( sizex ) );
633  }
634  catch( ... )
635  {
636  std::vector<float> vs( 4, 1. );
637  vs[0] = sizex;
638  ph->setProperty( "voxel_size", vs );
639  }
640  }
641 }
642 
643 
644 template < typename T >
645 inline
646 void AimsData<T>::setSizeY( float sizey )
647 {
648  if( !d->header )
650  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
651  if( ph )
652  {
653  std::vector<float> vs( 4, 1. );
654  try
655  {
656  carto::Object vso = ph->getProperty( "voxel_size" );
657  if( !vso.isNull() )
658  {
659  if( vso->size() >= 2 )
660  {
661  vso->setArrayItem( 1, carto::Object::value( sizey ) );
662  return;
663  }
664  else
665  {
666  if( vso->size() >= 1 )
667  vs[0] = vso->getArrayItem(0)->getScalar();
668  }
669  }
670  }
671  catch( ... )
672  {
673  }
674  vs[1] = sizey;
675  ph->setProperty( "voxel_size", vs );
676  }
677 }
678 
679 
680 template < typename T >
681 inline
682 void AimsData<T>::setSizeZ( float sizez )
683 {
684  if( !d->header )
686  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
687  if( ph )
688  {
689  std::vector<float> vs( 4, 1. );
690  try
691  {
692  carto::Object vso = ph->getProperty( "voxel_size" );
693  if( !vso.isNull() )
694  {
695  if( vso->size() >= 3 )
696  {
697  vso->setArrayItem( 2, carto::Object::value( sizez ) );
698  return;
699  }
700  else
701  {
702  carto::Object it;
703  int i;
704  for( i=0, it=vso->objectIterator();
705  it->isValid() && i<3; ++i, it->next() )
706  vs[i] = it->currentValue()->getScalar();
707  }
708  }
709  }
710  catch( ... )
711  {
712  }
713  vs[2] = sizez;
714  ph->setProperty( "voxel_size", vs );
715  }
716 }
717 
718 
719 template < typename T >
720 inline
721 void AimsData<T>::setSizeT( float sizet )
722 {
723  if( !d->header )
725  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
726  if( ph )
727  {
728  std::vector<float> vs( 4, 1. );
729  try
730  {
731  carto::Object vso = ph->getProperty( "voxel_size" );
732  if( !vso.isNull() )
733  {
734  if( vso->size() >= 4 )
735  {
736  vso->setArrayItem( 3, carto::Object::value( sizet ) );
737  return;
738  }
739  else
740  {
741  carto::Object it;
742  int i;
743  for( i=0, it=vso->objectIterator();
744  it->isValid() && i<4; ++i, it->next() )
745  vs[i] = it->currentValue()->getScalar();
746  }
747  }
748  }
749  catch( ... )
750  {
751  }
752  vs[3] = sizet;
753  ph->setProperty( "voxel_size", vs );
754  }
755 }
756 
757 
758 template < typename T >
759 inline
760 void
761 AimsData<T>::setSizeXYZT( float sizex, float sizey, float sizez, float sizet )
762 {
763  if( !d->header )
765  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
766  if( ph )
767  {
768  std::vector<float> vs( 4 );
769  vs[0] = sizex;
770  vs[1] = sizey;
771  vs[2] = sizez;
772  vs[3] = sizet;
773  ph->setProperty( "voxel_size", vs );
774  }
775 }
776 
777 
778 template < typename T >
779 inline
781 {
782  if( !d->header )
784  aims::PythonHeader *ph = dynamic_cast<aims::PythonHeader *>( d->header );
785  if( ph )
786  {
787  std::vector<float> vs( 4 );
788  vs[0] = other.sizeX();
789  vs[1] = other.sizeY();
790  vs[2] = other.sizeZ();
791  vs[3] = other.sizeT();
792  ph->setProperty( "voxel_size", vs );
793  }
794 }
795 
796 
797 template < typename T >
798 inline
799 const carto::AllocatorContext & AimsData<T>::allocator() const
800 {
801  return _volume->allocatorContext();
802 }
803 
804 
805 template < typename T >
806 inline
808 {
809  return d->header;
810 }
811 
812 
813 template < typename T >
814 inline
816 {
817  return d->header;
818 }
819 
820 
821 template<typename T>
822 inline
824 {
825  if( hdr != d->header )
826  {
827  aims::PythonHeader *mh;
828  if( !d->header )
829  {
830  d->header = mh = new aims::PythonHeader( *_volume );
831  }
832  else
833  {
834  mh = static_cast<aims::PythonHeader *>( d->header );
835  carto::Object oldvs;
836  try
837  {
838  // retreive old voxel size (if any)
839  oldvs = mh->getProperty( "voxel_size" );
840  }
841  catch( ... )
842  {
843  }
844  mh->clearProperties();
845  if( !oldvs.isNull() )
846  /* keep old voxel size which was not part of the dynamic header
847  in the old AimsData */
848  mh->setProperty( "voxel_size", oldvs );
849  }
850  const aims::PythonHeader
851  *ph = dynamic_cast<const aims::PythonHeader *>( hdr );
852  if( ph )
853  mh->copy( *ph, 1 );
854  // hdr used to transfer ownership to me
855  delete hdr;
856  }
857 }
858 
859 
860 template < typename T >
861 inline
862 typename AimsData<T>::reference
864 {
865  return *( begin() + n );
866 }
867 
868 
869 template < typename T >
870 inline
873 {
874  return *( begin() + n );
875 }
876 
877 
878 template < typename T >
879 inline
880 typename AimsData<T>::reference
883 {
884  return (*_volume)( x, y, z, t );
885 }
886 
887 
888 template < typename T >
889 inline
893  AimsData<T>::size_type t ) const
894 {
895  return (*_volume)( x, y, z, t );
896 }
897 
898 
899 template < typename T >
900 inline
901 typename AimsData<T>::reference
903 {
904  return (*this)( pt[0], pt[1], pt[2], pt[3] );
905 }
906 
907 
908 template < typename T >
909 inline
912 {
913  return (*this)( pt[0], pt[1], pt[2], pt[3] );
914 }
915 
916 
917 template < typename T >
918 inline
919 typename AimsData<T>::reference
921 {
922  return (*this)( pt[0], pt[1], pt[2], pt[3] );
923 }
924 
925 
926 template < typename T >
927 inline
930 {
931  return (*this)( pt[0], pt[1], pt[2], pt[3] );
932 }
933 
934 
935 template < typename T >
936 inline
937 typename AimsData<T>::reference
939 {
940  return (*this)( pt[0], pt[1], pt[2] );
941 }
942 
943 
944 template < typename T >
945 inline
948 {
949  return (*this)( pt[0], pt[1], pt[2] );
950 }
951 
952 
953 template < typename T >
954 inline
955 typename AimsData<T>::reference
957 {
958  return (*this)( pt[0], pt[1], pt[2] );
959 }
960 
961 
962 template < typename T >
963 inline
966 {
967  return (*this)( pt[0], pt[1], pt[2] );
968 }
969 
970 
971 template < typename T >
972 inline
973 typename AimsData<T>::reference
975 {
976  return (*this)( pt[0], pt[1] );
977 }
978 
979 
980 template < typename T >
981 inline
984 {
985  return (*this)( pt[0], pt[1] );
986 }
987 
988 
989 template < typename T >
990 inline
991 typename AimsData<T>::reference
993 {
994  return (*this)( pt[0], pt[1] );
995 }
996 
997 
998 template < typename T >
999 inline
1002 {
1003  return (*this)( pt[0], pt[1] );
1004 }
1005 
1006 
1007 template < typename T >
1008 inline
1010 {
1011  return volume()->min();
1012 }
1013 
1014 
1015 template < typename T >
1016 inline
1018 {
1019  return volume()->max();
1020 }
1021 
1022 
1023 template < typename T >
1024 inline
1025 T AimsData<T>::minIndex( int* xx, int* yy, int* zz, int* tt ) const
1026 {
1027  int minxind = 0,minyind = 0,minzind = 0,mintind = 0;
1028  T mini;
1029  const_iterator it = begin() + oFirstPoint();
1030 
1031  mini = *it;
1032  int x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1033 
1034  for ( t = 0; t < tm; t++ )
1035  {
1036  for ( z = 0; z < zm; z++ )
1037  {
1038  for ( y = 0; y < ym; y++ )
1039  {
1040  for ( x = 0; x < xm; x++ )
1041  {
1042  if ( *it < mini )
1043  {
1044  mini = *it;
1045  minxind = x;
1046  minyind = y;
1047  minzind = z;
1048  mintind = t;
1049  }
1050  it++;
1051  }
1052  it += oPointBetweenLine();
1053  }
1054  it += oLineBetweenSlice();
1055  }
1056  it += oSliceBetweenVolume();
1057  }
1058  if ( xx )
1059  *xx = minxind;
1060  if ( yy )
1061  *yy = minyind;
1062  if ( zz )
1063  *zz = minzind;
1064  if ( tt )
1065  *tt = mintind;
1066 
1067  return mini;
1068 }
1069 
1070 
1071 template < typename T >
1072 inline
1073 T AimsData<T>::maxIndex( int* xx, int* yy, int* zz, int* tt ) const
1074 {
1075  int maxxind = 0,maxyind = 0,maxzind = 0,maxtind = 0;
1076  T maxi;
1077  const_iterator it = begin() + oFirstPoint();
1078 
1079  maxi = *it;
1080  int x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1081 
1082  for ( t = 0; t < tm; t++ )
1083  {
1084  for ( z = 0; z < zm; z++ )
1085  {
1086  for ( y = 0; y < ym; y++ )
1087  {
1088  for ( x = 0; x < xm; x++ )
1089  {
1090  if ( *it > maxi )
1091  {
1092  maxi = *it;
1093  maxxind = x;
1094  maxyind = y;
1095  maxzind = z;
1096  maxtind = t;
1097  }
1098  it++;
1099  }
1100  it += oPointBetweenLine();
1101  }
1102  it += oLineBetweenSlice();
1103  }
1104  it += oSliceBetweenVolume();
1105  }
1106  if ( xx )
1107  *xx = maxxind;
1108  if ( yy )
1109  *yy = maxyind;
1110  if ( zz )
1111  *zz = maxzind;
1112  if ( tt )
1113  *tt = maxtind;
1114 
1115  return maxi;
1116 }
1117 
1118 
1119 template < typename T >
1120 inline
1121 void AimsData<T>::fillBorder( const T& val )
1122 {
1123  carto::VolumeRef<T> bigger = _volume->refVolume();
1124  if( bigger.isNull() )
1125  return;
1126  T *it;
1127  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1128  long of = &_volume->at( 0, 0, 0, 0 ) - &bigger->at( 0, 0, 0, 0 ),
1129  op = &_volume->at( 0, 1, 0, 0 ) - &_volume->at( xm, 0, 0, 0 ),
1130  ol = &_volume->at( 0, 0, 1, 0 ) - &_volume->at( 0, ym, 0, 0 );
1131 
1132  for ( t = 0; t < tm; t++ )
1133  {
1134  it = &bigger->at( 0, 0, 0, t );
1135  for ( x = 0; x < of; x++ )
1136  *it++ = val;
1137  for ( z = 0; z < zm; z++ )
1138  {
1139  for ( y = 0; y < ym; y++ )
1140  {
1141  it += xm;
1142  for ( x = 0; x < op; x++ )
1143  *it++ = val;
1144  }
1145  for ( x = 0; x < ol; x++ )
1146  *it++ = val;
1147  }
1148  for ( x = 0; x < of - op - ol; x++ )
1149  *it++ = val;
1150  }
1151 }
1152 
1153 
1154 template<typename T>
1156 {
1157  AimsData<T> dat( *this );
1158  if( !_volume->refVolume().isNull() )
1159  {
1160  // border has to be copied
1162  _volume->refVolume()->getSizeX(), _volume->refVolume()->getSizeY(),
1163  _volume->refVolume()->getSizeZ(), _volume->refVolume()->getSizeT(),
1164  _volume->refVolume()->allocatorContext(),
1165  _volume->refVolume()->allocatorContext().isAllocated() ) );
1166 
1167  if( _volume->refVolume()->allocatorContext().isAllocated() )
1168  transfer( _volume->refVolume(), rvol );
1169 
1170  dat._volume.reset( new carto::Volume<T>( rvol, _volume->posInRefVolume(),
1171  typename carto::Volume<T>::Position4Di( _volume->getSizeX(),
1172  _volume->getSizeY(),
1173  _volume->getSizeZ(),
1174  _volume->getSizeT() ) ) );
1175  dat._volume->header().copyProperties(
1176  carto::Object::reference( _volume->header() ) );
1177  }
1178  else
1179  dat._volume.reset( new carto::Volume<T>( *_volume ) );
1180  delete dat.d->header;
1181  dat.d->header = new aims::PythonHeader( *dat._volume );
1182  dat.initBorder();
1183 
1184  return dat;
1185 }
1186 
1187 
1188 template < typename T >
1189 inline
1191 {
1192  ASSERT( dimT() == 1 && other.dimT() == 1 &&
1193  dimZ() == 1 && other.dimZ() == 1 );
1194  ASSERT( dimY() == other.dimX() );
1195 
1196  AimsData<T> prod( dimX(), other.dimY(), 1, 1,
1197  std::max( borderWidth(), other.borderWidth() ) );
1198  for ( long y = 0; y < other.dimY(); y++ )
1199  for ( long x = 0; x < dimX(); x++ )
1200  {
1201  prod( x, y ) = T( 0 );
1202  for ( long k = 0; k < dimY(); k++ )
1203  prod( x, y ) += (*this)( x, k ) * other( k, y );
1204  }
1205 
1206  return prod;
1207 }
1208 
1209 
1210 template < typename T >
1211 inline
1213 {
1214  AimsData<T> tmp( dimY(), dimX(), dimZ(), dimT(), borderWidth() );
1216  *ph = dynamic_cast<aims::PythonHeader *>( header() );
1217  if( ph )
1218  {
1219  ph = static_cast<aims::PythonHeader *>( ph->cloneHeader() );
1220  if( ph->hasProperty( "volume_dimension" ) )
1221  ph->removeProperty( "volume_dimension" );
1222  if( ph->hasProperty( "voxel_size" ) )
1223  ph->removeProperty( "voxel_size" );
1224  tmp.setHeader( ph );
1225  }
1226  tmp.setSizeXYZT( sizeY(), sizeX(), sizeZ(), sizeT() );
1227  tmp.fillBorder( T( 0 ) );
1228 
1229  long x, xm = dimX(), y, ym = dimY(), z, zm = dimZ(), t, tm = dimT();
1230 
1231  for ( t = 0; t < tm; t++ )
1232  for ( z = 0; z < zm; z++ )
1233  for ( y = 0; y < ym; y++ )
1234  for ( x = 0; x < xm; x++ )
1235  tmp( y, x, z, t ) = (*this)( x, y, z, t );
1236 
1237  *this = tmp;
1238  return *this;
1239 }
1240 
1241 
1242 template < typename T >
1243 inline
1245  const AimsData<T>& secondThing )
1246 {
1248  v += carto::VolumeRef<T>(secondThing.volume());
1249  return v;
1250 }
1251 
1252 
1253 template < typename T >
1254 inline
1256  const AimsData<T>& secondThing )
1257 {
1259  v -= carto::VolumeRef<T>(secondThing.volume());
1260  return v;
1261 }
1262 
1263 template < typename T >
1264 inline
1265 AimsData<T> operator * ( const AimsData<T>& firstThing, float scale )
1266 {
1268  v *= scale;
1269  return v;
1270 }
1271 
1272 
1273 // macros
1274 
1275 #define ForEach4d( 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 ForEach3d( 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 ForEach2d( thing , x , y) \
1287  for ( y = 0; y < thing.dimY(); y++ ) \
1288  for ( x = 0; x < thing.dimX(); x++ )
1289 
1290 #define ForEach1d( thing , x) \
1291  for ( x = 0; x < thing.dimX(); x++ )
1292 
1293 
1294 #define ForEach4dp( thing , x , y , z , t) \
1295  for ( t = 0; t < thing->dimT(); t++ ) \
1296  for ( z = 0; z < thing->dimZ(); z++ ) \
1297  for ( y = 0; y < thing->dimY(); y++ ) \
1298  for ( x = 0; x < thing->dimX(); x++ )
1299 
1300 #define ForEach3dp( thing , x , y , z) \
1301  for ( z = 0; z < thing->dimZ(); z++ ) \
1302  for ( y = 0; y < thing->dimY(); y++ ) \
1303  for ( x = 0; x < thing->dimX(); x++ )
1304 
1305 #define ForEach2dp( thing , x , y) \
1306  for ( y = 0; y < thing->dimY(); y++ ) \
1307  for ( x = 0; x < thing->dimX(); x++ )
1308 
1309 #define ForEach1dp( thing , x) \
1310  for ( x = 0; x < thing->dimX(); x++ )
1311 
1312 
1313 class DtiTensor;
1314 
1315 namespace carto
1316 {
1317  // instanciations of Volume classes
1318 
1319  extern template class VolumeProxy<DtiTensor*>;
1320  extern template class Volume<DtiTensor*>;
1321 
1322 }
1323 
1324 
1325 #endif
1326 
int oLineBetweenSlice() const
Number of lines between 2 consecutive slices.
Definition: border.h:250
void setSizeT(float sizet)
T & reference
basic reference
reference operator()(size_type x=0, size_type y=0, size_type z=0, size_type t=0)
AimsData< T > & transpose()
const T * const_iterator
basic constant iterator
int dimZ() const
virtual bool getProperty(const std::string &, Object &) const
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
int _oSlice
Length of a slice.
Definition: border.h:132
int oPointBetweenLine() const
Offset between the end of a line and the start of the consecutive line.
Definition: border.h:236
void _setBorder(int dimx, int dimy, int dimz, int width)
Function that sets up all protected datas.
iterator begin()
static int borderWidth(carto::rc_ptr< carto::Volume< T > > vol)
T * iterator
basic iterator
float sizeZ() const
const std::vector< int > & borders() const
Sizes of the border.
The base class to manage borders on data containers.
Definition: border.h:49
ptrdiff_t difference_type
difference type
int dimY() const
virtual void copy(const PythonHeader &, bool keepUuid=false)
float sizeT() const
The class for EcatSino data write operation.
Definition: border.h:44
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)
void setSizeX(float sizex)
virtual bool removeProperty(const std::string &)
void setSizeY(float sizey)
void setHeader(aims::Header *hdr)
int _oPointBetweenLine
Offset between two consecutive lines.
Definition: border.h:130
virtual Header * cloneHeader(bool keepUuid=false) const
float sizeX() const
const T & at(long x, long y=0, long z=0, long t=0) const
int _oSliceBetweenVolume
Offset between two consecutive volumes.
Definition: border.h:138
void transfer(const Volume< T > &src, Volume< T > &dst)
int _oFirstPoint
Offset up to first point.
Definition: border.h:124
void fillBorder(const T &val)
bool empty() const
carto::Object getObjectHeader(AimsData< T > &obj)
virtual ~AimsData()
virtual void clearProperties()
T * pointer
basic pointer
AimsData< T > & operator=(carto::rc_ptr< carto::Volume< T > > vol)
AimsData< T > clone() const
T minIndex(int *x, int *y, int *z, int *t) const
const aims::Header * header() const
Volume< T > deepcopy(const Volume< T > &src)
AimsData< T > operator*(const AimsData< T > &firstThing, float scale)
AimsData< T > cross(const AimsData< T > &other)
int _oLineBetweenSlice
Offset between two consecutive slices.
Definition: border.h:134
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:168
float sizeY() const
static Object value()
carto::rc_ptr< carto::Volume< T > > volume()
int _oVolume
Length of a volume.
Definition: border.h:136
T maxIndex(int *x, int *y, int *z, int *t) const
const carto::AllocatorContext & allocator() const
T * get() const
int dimT() const
int oSliceBetweenVolume() const
Number of slices between 2 consecutive volumes.
Definition: border.h:264
T minimum() const
int _oLine
Length of a line.
Definition: border.h:128
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)
const T & const_reference
basic constant reference
iterator end()
void reset(T *p=NULL)
virtual bool hasProperty(const std::string &) const
#define ASSERT(EX)
void setSizeZ(float sizez)
aims::Header * header
int oFirstPoint() const
Offset from the start of the allocated memory to the first point.
Definition: border.h:215
T maximum() const
reference operator[](size_type n)
int dimX() const
int borderWidth() const
Usefull offsets for A.I.M.S.
Definition: border.h:200