cartodata  4.5.0
volumebase_d.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef CARTODATA_VOLUME_VOLUMEBASE_D_H
35 #define CARTODATA_VOLUME_VOLUMEBASE_D_H
36 
37 //--- cartodata --------------------------------------------------------------
44 //--- cartobase --------------------------------------------------------------
45 #include <cartobase/type/limits.h>
50 //--- soma-io ----------------------------------------------------------------
52 //--- std --------------------------------------------------------------------
53 #include <cstdlib>
54 #include <algorithm>
55 #include <stdexcept>
56 #include <string>
57 #include <stdio.h>
58 //----------------------------------------------------------------------------
59 
60 namespace carto
61 {
62 //============================================================================
63 // CONSTRUCTORS
64 //============================================================================
65 
66  /***************************************************************************
67  * Default Constructor
68  **************************************************************************/
69  template < typename T >
70  Volume< T >::Volume( int sizeX, int sizeY, int sizeZ, int sizeT,
71  const AllocatorContext& allocatorContext,
72  bool allocated )
73  : VolumeProxy< T >( sizeX, sizeY, sizeZ, sizeT ),
74  _items( 0U, allocatorContext )
75 #ifndef CARTO_USE_BLITZ
76  ,
77  _lineoffset( 0 ),
78  _sliceoffset( 0 ),
79  _volumeoffset( 0 )
80 #endif
81  {
82  allocate( -1, -1, -1, -1, allocated, allocatorContext );
83  }
84 
85  template < typename T >
87  const AllocatorContext& allocatorContext,
88  bool allocated ):
89  VolumeProxy< T >( size[0] > 0 ? size[0] : 1,
90  size[1] > 0 ? size[1] : 1,
91  size[2] > 0 ? size[2] : 1,
92  size[3] > 0 ? size[3] : 1 ),
93  _items( 0U, allocatorContext )
94 #ifndef CARTO_USE_BLITZ
95  ,
96  _lineoffset( 0 ),
97  _sliceoffset( 0 ),
98  _volumeoffset( 0 )
99 #endif
100  {
101  allocate( -1, -1, -1, -1, allocated, allocatorContext );
102  }
103 
104  /***************************************************************************
105  * Constructor with border
106  **************************************************************************/
107 
108  template < typename T >
109  void Volume< T >::constructBorders( const Position4Di & bordersize,
110  const AllocatorContext& allocatorContext,
111  bool allocated )
112  {
113  if( bordersize != Position4Di() )
114  {
115  _refvol.reset( new Volume<T>( VolumeProxy<T>::getSizeX() + bordersize[0]*2,
116  VolumeProxy<T>::getSizeY() + bordersize[1]*2,
117  VolumeProxy<T>::getSizeZ() + bordersize[2]*2,
118  VolumeProxy<T>::getSizeT() + bordersize[3]*2,
119  allocatorContext, allocated ) );
120 
121  allocate( -1, -1, -1, -1, true,
122  _refvol->allocatorContext().isAllocated()
123  ? AllocatorContext( AllocatorStrategy::NotOwner,
124  rc_ptr<DataSource>( new BufferDataSource
125  ( (char *) &(*_refvol)( bordersize[0], bordersize[1],
126  bordersize[2], bordersize[3] ),
131  * sizeof(T) ) ) )
132  : allocatorContext );
133  if( _refvol->allocatorContext().isAllocated() )
134  {
135  // fix offsets
136 #ifdef CARTO_USE_BLITZ
137  _blitz.reference
138  ( blitz::Array<T,4>
139  ( &_items[0],
140  blitz::shape( VolumeProxy<T>::getSizeX(),
144  blitz::shape( 1, &(*_refvol)( 0, 1, 0 ) - &(*_refvol)( 0, 0, 0 ),
145  &(*_refvol)( 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 ),
146  &(*_refvol)( 0, 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 )
147  ),
148  blitz::GeneralArrayStorage<4>
149  ( blitz::shape( 0, 1, 2, 3 ), true ) ) );
150 #else
151  _lineoffset = &(*_refvol)( 0, 1, 0 ) - &(*_refvol)( 0, 0, 0 );
152  _sliceoffset = &(*_refvol)( 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 );
153  _volumeoffset = &(*_refvol)( 0, 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 );
154 #endif
155  }
156  }
157  else // no border
158  {
159  allocate( -1, -1, -1, -1, allocated, allocatorContext );
160  }
161  }
162 
163  template < typename T >
164  Volume< T >::Volume( int sizeX, int sizeY, int sizeZ, int sizeT,
165  const Position4Di & bordersize,
166  const AllocatorContext& allocatorContext,
167  bool allocated )
168  : VolumeProxy< T >( sizeX, sizeY, sizeZ, sizeT ),
169  _items( 0U, AllocatorContext( AllocatorStrategy::NotOwner,
170  DataSource::none() ) ),
171 #ifndef CARTO_USE_BLITZ
172  _lineoffset( 0 ),
173  _sliceoffset( 0 ),
174  _volumeoffset( 0 ),
175 #endif
176  _pos( bordersize[0], bordersize[1], bordersize[2], bordersize[3] )
177  {
178  constructBorders( bordersize, allocatorContext, allocated );
179  }
180 
181  template < typename T >
183  const Position4Di & bordersize,
184  const AllocatorContext& allocatorContext,
185  bool allocated ):
186  VolumeProxy< T >( size[0] > 0 ? size[0] : 1,
187  size[1] > 0 ? size[1] : 1,
188  size[2] > 0 ? size[2] : 1,
189  size[3] > 0 ? size[3] : 1 ),
190  _items( 0U, AllocatorContext( AllocatorStrategy::NotOwner,
191  DataSource::none() ) ),
192 #ifndef CARTO_USE_BLITZ
193  _lineoffset( 0 ),
194  _sliceoffset( 0 ),
195  _volumeoffset( 0 ),
196 #endif
197  _pos( bordersize[0], bordersize[1], bordersize[2], bordersize[3] )
198  {
199  constructBorders( bordersize, allocatorContext, allocated );
200  }
201 
202  template < typename T >
203  Volume< T >::Volume( int sizeX, int sizeY, int sizeZ,
204  int sizeT, int bordersize,
205  const AllocatorContext& allocatorContext,
206  bool allocated )
207  : VolumeProxy< T >( sizeX, sizeY, sizeZ, sizeT ),
208  _items( 0U, AllocatorContext( AllocatorStrategy::NotOwner,
209  DataSource::none() ) ),
210 #ifndef CARTO_USE_BLITZ
211  _lineoffset( 0 ),
212  _sliceoffset( 0 ),
213  _volumeoffset( 0 ),
214 #endif
215  _pos( bordersize, bordersize, bordersize, 0 )
216  {
217  constructBorders( Position4Di( bordersize, bordersize, bordersize, 0 ),
218  allocatorContext, allocated );
219  }
220 
221  template < typename T >
223  int bordersize,
224  const AllocatorContext& allocatorContext,
225  bool allocated ):
226  VolumeProxy< T >( size[0] > 0 ? size[0] : 1,
227  size[1] > 0 ? size[1] : 1,
228  size[2] > 0 ? size[2] : 1,
229  size[3] > 0 ? size[3] : 1 ),
230  _items( 0U, AllocatorContext( AllocatorStrategy::NotOwner,
231  DataSource::none() ) ),
232 #ifndef CARTO_USE_BLITZ
233  _lineoffset( 0 ),
234  _sliceoffset( 0 ),
235  _volumeoffset( 0 ),
236 #endif
237  _pos( bordersize, bordersize, bordersize, 0 )
238  {
239  constructBorders( Position4Di( bordersize, bordersize, bordersize, 0 ),
240  allocatorContext, allocated );
241  }
242 
243  /***************************************************************************
244  * Buffer Constructor
245  **************************************************************************/
246  template < typename T >
247  Volume< T >::Volume( int sizeX, int sizeY, int sizeZ, int sizeT, T* buffer )
248  : VolumeProxy< T >( sizeX, sizeY, sizeZ, sizeT ),
249  _items( sizeX * sizeY * sizeZ * sizeT, buffer )
250 #ifndef CARTO_USE_BLITZ
251  ,
252  _lineoffset( 0 ),
253  _sliceoffset( 0 ),
254  _volumeoffset( 0 )
255 #endif
256  {
257  allocate( -1, -1, -1, -1, true, allocatorContext() );
258  }
259 
260  template < typename T >
261  Volume< T >::Volume( const Position4Di & size, T* buffer ):
262  VolumeProxy< T >( size[0] > 0 ? size[0] : 1,
263  size[1] > 0 ? size[1] : 1,
264  size[2] > 0 ? size[2] : 1,
265  size[3] > 0 ? size[3] : 1 ),
266  _items( (long)(size[0] > 0 ? size[0] : 1) *
267  (long)(size[1] > 0 ? size[1] : 1) *
268  (long)(size[2] > 0 ? size[2] : 1) *
269  (long)(size[3] > 0 ? size[3] : 1), buffer )
270 #ifndef CARTO_USE_BLITZ
271  ,
272  _lineoffset( 0 ),
273  _sliceoffset( 0 ),
274  _volumeoffset( 0 )
275 #endif
276  {
277  allocate( -1, -1, -1, -1, true, allocatorContext() );
278  }
279 
280 
281  /***************************************************************************
282  * View Constructor
283  **************************************************************************/
284  template<typename T> inline
286  const Position4Di & pos, const Position4Di & size,
287  const AllocatorContext & allocContext )
288  : VolumeProxy<T>( size[0] >= 0 ? size[0] :
289  other->allocatorContext().isAllocated() ? other->getSizeX() : 1,
290  size[1] >= 0 ? size[1] :
291  other->allocatorContext().isAllocated() ? other->getSizeY() : 1,
292  size[2] >= 0 ? size[2] :
293  other->allocatorContext().isAllocated() ? other->getSizeZ() : 1,
294  size[3] >= 0 ? size[3] :
295  other->allocatorContext().isAllocated() ? other->getSizeT() : 1 ),
296  _items( 0U,
297  other->allocatorContext().isAllocated()
298  ? AllocatorContext( AllocatorStrategy::NotOwner,
299  rc_ptr<DataSource>( new BufferDataSource
300  ( (char *) &(*other)( pos[0], pos[1],
301  pos[2], pos[3] ),
302  size[0] * size[1] * size[2] * size[3]
303  * sizeof(T) ) ) )
304  : allocContext ),
305  _refvol( other ),
306  _pos( pos )
307 #ifndef CARTO_USE_BLITZ
308  ,
309  _lineoffset( 0 ),
310  _sliceoffset( 0 ),
311  _volumeoffset( 0 )
312 #endif
313  {
314  allocate( -1, -1, -1, -1, true, other->allocatorContext().isAllocated()
315  ? AllocatorContext( AllocatorStrategy::NotOwner,
316  rc_ptr<DataSource>( new BufferDataSource
317  ( (char *) &(*other)( pos[0], pos[1],
318  pos[2], pos[3] ),
319  size[0] * size[1] * size[2] * size[3]
320  * sizeof(T) ) ) )
321  : allocContext );
322  if( other->allocatorContext().isAllocated() )
323  {
324  // fix offsets
325 #ifdef CARTO_USE_BLITZ
326  _blitz.reference
327  ( blitz::Array<T,4>
328  ( &_items[0],
329  blitz::shape( VolumeProxy<T>::getSizeX(),
333  blitz::shape( 1, &(*other)( 0, 1, 0 ) - &(*other)( 0, 0, 0 ),
334  &(*other)( 0, 0, 1 ) - &(*other)( 0, 0, 0 ),
335  &(*other)( 0, 0, 0, 1 ) - &(*other)( 0, 0, 0 ) ),
336  blitz::GeneralArrayStorage<4>
337  ( blitz::shape( 0, 1, 2, 3 ), true ) ) );
338 #else
339  _lineoffset = &(*other)( 0, 1, 0 ) - &(*other)( 0, 0, 0 );
340  _sliceoffset = &(*other)( 0, 0, 1 ) - &(*other)( 0, 0, 0 );
341  _volumeoffset = &(*other)( 0, 0, 0, 1 ) - &(*other)( 0, 0, 0 );
342 #endif
343  }
344 
345  /* copy voxel_size from underlying volume, if any.
346  This should probably be more general, but cannot be applied to all
347  header properties (size, transformations...).
348  WARNING: Moreover here we do not guarantee to keep both voxel_size
349  unique: we point to the same vector of values for now, but it can be
350  replaced (thus, duplicated) by a setProperty().
351  We could use a addBuiltinProperty(), but then the voxel size has to be
352  stored in a fixed location somewhere.
353  */
354  try
355  {
356  carto::Object vs = other->header().getProperty( "voxel_size" );
357  this->header().setProperty( "voxel_size", vs );
358  }
359  catch( ... )
360  {
361  // never mind.
362  }
363  }
364 
365  /***************************************************************************
366  * Copy Constructor
367  **************************************************************************/
368  template < typename T >
370  : RCObject(),
371  VolumeProxy< T >( other ),
372  _items( other._items ),
373 #ifdef CARTO_USE_BLITZ
374  // TODO: test blitz ownership / strides
375  // _blitz = other.blitz;
376  _blitz( &_items[0],
377  blitz::shape( VolumeProxy<T>::_sizeX,
378  VolumeProxy<T>::_sizeY,
379  VolumeProxy<T>::_sizeZ,
380  VolumeProxy<T>::_sizeT ),
381  blitz::GeneralArrayStorage<4>
382  ( blitz::shape( 0, 1, 2, 3 ), true ) ),
383 #else
384  _lineoffset( other._lineoffset ),
385  _sliceoffset( other._sliceoffset ),
386  _volumeoffset( other._volumeoffset ),
387 #endif
388  _refvol( other.refVolume().get() ?
389  new Volume<T>( *other.refVolume() ) : 0 ),
390  _pos( other.posInRefVolume() )
391  {
392  if( _refvol.get() ) // view case: the underlying volume is copied.
393  {
394  Position4Di pos = other.posInRefVolume();
395  allocate( -1, -1, -1, -1, true, _refvol->allocatorContext().isAllocated()
396  ? AllocatorContext( AllocatorStrategy::NotOwner,
397  rc_ptr<DataSource>( new BufferDataSource
398  ( (char *) &(*_refvol)( pos[0], pos[1], pos[2], pos[3] ),
402  * sizeof(T) ) ) )
403  : AllocatorContext( other.allocatorContext() ) );
404  if( _refvol->allocatorContext().isAllocated() )
405  {
406  // fix offsets
407 #ifdef CARTO_USE_BLITZ
408  _blitz.reference
409  ( blitz::Array<T,4>
410  ( &_items[0],
411  blitz::shape( VolumeProxy<T>::getSizeX(),
415  blitz::shape( 1, &other( 0, 1, 0 ) - &other( 0, 0, 0 ),
416  &other( 0, 0, 1 ) - &other( 0, 0, 0 ),
417  &other( 0, 0, 0, 1 ) - &other( 0, 0, 0 ) ),
418  blitz::GeneralArrayStorage<4>
419  ( blitz::shape( 0, 1, 2, 3 ), true ) ) );
420 #else
421  _lineoffset = &other( 0, 1, 0 ) - &other( 0, 0, 0 );
422  _sliceoffset = &other( 0, 0, 1 ) - &other( 0, 0, 0 );
423  _volumeoffset = &other( 0, 0, 0, 1 ) - &other( 0, 0, 0 );
424 #endif
425  }
426  }
427  }
428 
429  template < typename T >
431  {
432  }
433 
434 //============================================================================
435 // M E T H O D S
436 //============================================================================
437 
438  template < typename T > inline
439  const AllocatorContext& Volume<T>::allocatorContext() const
440  {
441  return _items.allocatorContext();
442  }
443 
444  template <typename T> inline
446  {
447  return _refvol;
448  }
449 
450  template <typename T> inline
452  {
453  return _pos;
454  }
455 
456  template <typename T> inline
458 
459  if ( !allocatorContext().isAllocated()
460  || (allocatorContext().accessMode() == AllocatorStrategy::NotOwner) ) {
461 
462  // Free old buffer
463  _items.free();
464 
465  if (_refvol.get()) {
466  // Recreate items buffer that reference volume
467  // using correct sizes and position
468  _items = AllocatedVector<T>( 0U,
469  _refvol->allocatorContext().isAllocated()
470  ? AllocatorContext( AllocatorStrategy::NotOwner,
471  rc_ptr<DataSource>( new BufferDataSource
472  ( (char *) &(*(_refvol))( _pos[0], _pos[1],
473  _pos[2], _pos[3] ),
478  * sizeof(T) ) ) )
479  : allocatorContext() );
480 
481  if ( _refvol->allocatorContext().isAllocated() )
482  {
483  // fix offsets
484 #ifdef CARTO_USE_BLITZ
485  _blitz.reference
486  ( blitz::Array<T,4>
487  ( &_items[0],
488  blitz::shape( VolumeProxy<T>::getSizeX(),
492  blitz::shape( 1, &(*_refvol)( 0, 1, 0 ) - &(*_refvol)( 0, 0, 0 ),
493  &(*_refvol)( 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 ),
494  &(*_refvol)( 0, 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 ) ),
495  blitz::GeneralArrayStorage<4>
496  ( blitz::shape( 0, 1, 2, 3 ), true ) ) );
497 #else
498  _lineoffset = &(*_refvol)( 0, 1, 0 ) - &(*_refvol)( 0, 0, 0 );
499  _sliceoffset = &(*_refvol)( 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 );
500  _volumeoffset = &(*_refvol)( 0, 0, 0, 1 ) - &(*_refvol)( 0, 0, 0 );
501 #endif
502  }
503 
504  /* copy voxel_size from underlying volume, if any.
505  This should probably be more general, but cannot be applied to all
506  header properties (size, transformations...).
507  WARNING: Moreover here we do not guarantee to keep both voxel_size
508  unique: we point to the same vector of values for now, but it can be
509  replaced (thus, duplicated) by a setProperty().
510  We could use a addBuiltinProperty(), but then the voxel size has to be
511  stored in a fixed location somewhere.
512  */
513  try
514  {
515  carto::Object vs = _refvol->header().getProperty( "voxel_size" );
516  this->header().setProperty( "voxel_size", vs );
517  }
518  catch( ... )
519  {
520  // never mind.
521  }
522  }
523  }
524  }
525 
526  template <typename T> inline
528  if (pos != _pos) {
529  _pos = pos;
530  updateItemsBuffer();
531  }
532  }
533 
534  template <typename T> inline
535  void Volume<T>::setRefVolume( const rc_ptr<Volume<T> > & refvol) {
536  if (refvol.get() != _refvol.get()) {
537  _refvol = refvol;
538  updateItemsBuffer();
539  }
540  }
541 
542  template <typename T> inline
543  std::vector<int> Volume<T>::getBorders() const
544  {
545  std::vector<int> borders(8, 0);
546  if (_refvol.get())
547  {
548  borders[0] = _pos[0];
549  borders[1] = _refvol->_sizeX - VolumeProxy<T>::_sizeX - _pos[0];
550  borders[2] = _pos[1];
551  borders[3] = _refvol->_sizeY - VolumeProxy<T>::_sizeY - _pos[1];
552  borders[4] = _pos[2];
553  borders[5] = _refvol->_sizeZ - VolumeProxy<T>::_sizeZ - _pos[2];
554  borders[6] = _pos[3];
555  borders[7] = _refvol->_sizeT - VolumeProxy<T>::_sizeT - _pos[3];
556  }
557 
558  return borders;
559  }
560 
561  template <typename T> inline
562  std::vector<size_t> Volume<T>::getStrides() const
563  {
564  std::vector<size_t> strides(4);
565 
566 #ifdef CARTO_USE_BLITZ
567  const blitz::TinyVector<int, 4>& bstrides = _blitz.stride();
568  for (int d = 0; d < 4; ++d)
569  strides[d] = bstrides[d];
570 #else
571  strides[0] = 1;
572  strides[1] = _lineoffset;
573  strides[2] = _sliceoffset;
574  strides[3] = _volumeoffset;
575 #endif
576 
577  return strides;
578  }
579 
580  template < typename T >
582  {
583 
584  if( &other == this )
585  return *this;
586 
587  bool b = Headered::signalsBlocked();
588  if( !b )
589  Headered::blockSignals( true );
590  this->VolumeProxy< T >::operator=( other );
591  _items = other._items;
592 #ifdef CARTO_USE_BLITZ
593  // TODO: test blitz ownership / strides
594  // _blitz.reference( other.blitz );
595  _blitz.reference( blitz::Array<T,4>
596  ( &_items[0],
597  blitz::shape( VolumeProxy<T>::_sizeX,
601  blitz::GeneralArrayStorage<4>
602  ( blitz::shape( 0, 1, 2, 3 ), true ) ) );
603 #else
604  _lineoffset = other._lineoffset;
605  _sliceoffset = other._sliceoffset;
606  _volumeoffset = other._volumeoffset;
607 #endif
608  _refvol = other._refvol;
609  _pos = other._pos;
610 
611  initialize();
612 
613  if( !b )
614  Headered::blockSignals( false );
615 
616  return *this;
617 
618  }
619 
620  template < typename T >
622  {
623 
624 #ifdef CARTO_USE_BLITZ
625  return _blitz.begin();
626 #else
627  return _items.begin();
628 #endif
629 
630  }
631 
632 
633  template < typename T >
635  {
636 
637 #ifdef CARTO_USE_BLITZ
638  return _blitz.end();
639 #else
640  return _items.end();
641 #endif
642 
643  }
644 
645 
646  template < typename T >
648  {
649 
650 #ifdef CARTO_USE_BLITZ
651  return _blitz.begin();
652 #else
653  return _items.begin();
654 #endif
655 
656  }
657 
658 
659  template < typename T >
661  {
662 
663 #ifdef CARTO_USE_BLITZ
664  return _blitz.end();
665 #else
666  return _items.end();
667 #endif
668 
669  }
670 
671 
672  template < typename T >
674  {
675 
676  // initializing headered stuff
677  this->Headered::initialize();
678 
679  // creating size filter
680  std::set< std::string > sizePropertyNames;
681  sizePropertyNames.insert( "sizeX" );
682  sizePropertyNames.insert( "sizeY" );
683  sizePropertyNames.insert( "sizeZ" );
684  sizePropertyNames.insert( "sizeT" );
686  sizeRcPropertyFilter( new PropertyFilter( "size", sizePropertyNames ) );
687 
688  // adding size filter to headered and connecting signal to slot
689  Headered::addPropertyFilter( sizeRcPropertyFilter );
690  Headered::connect( sizeRcPropertyFilter->getName(),
691  ::sigc::mem_fun( *this, &Volume< T >::slotSizeChanged ) );
692 
693  }
694 
695 
696  template < typename T >
697  void Volume< T >::allocate( int oldSizeX,
698  int oldSizeY,
699  int oldSizeZ,
700  int oldSizeT,
701  bool allocate,
702  const AllocatorContext& ac )
703  {
704 
705  unsigned long long int sizeXY =
706  (unsigned long long int) VolumeProxy<T>::_sizeX
707  * (unsigned long long int) VolumeProxy<T>::_sizeY;
708  unsigned long long int sizeXYZ = sizeXY
709  * (unsigned long long int) VolumeProxy<T>::_sizeZ;
710  unsigned long long int sizeXYZT = sizeXYZ
711  * (unsigned long long int) VolumeProxy<T>::_sizeT;
712 
713  if ( sizeXYZT * sizeof(T) >
714  (unsigned long long int) std::numeric_limits< size_t >::max() )
715  {
716 
717  throw std::runtime_error
718  ( std::string( "attempt to allocate a volume which size is greater "
719  "than allowed by the system (" )
720  + toString( std::numeric_limits< size_t >::max() ) + " bytes)" );
721 
722  }
723 
724  if ( !allocate // why !allocate ?
725  || !_items.allocatorContext().isAllocated()
726  || ( ( oldSizeX == -1 ) &&
727  ( oldSizeY == -1 ) &&
728  ( oldSizeZ == -1 ) &&
729  ( oldSizeT == -1 ) ) )
730  {
731 
732  // allocating memory space
733  _items.free();
734  if( allocate )
735  _items.allocate( ( size_t )sizeXYZT, ac );
736  }
737  else if ( ( oldSizeX != VolumeProxy<T>::_sizeX ) ||
738  ( oldSizeY != VolumeProxy<T>::_sizeY ) ||
739  ( oldSizeZ != VolumeProxy<T>::_sizeZ ) ||
740  ( oldSizeT != VolumeProxy<T>::_sizeT )
741  || &ac != &_items.allocatorContext() )
742  {
743 
744  // allocating a new memory space
745  AllocatedVector<T> newItems( ( size_t )sizeXYZT, ac );
746 
747  int minSizeX = std::min( oldSizeX, VolumeProxy<T>::_sizeX );
748  int minSizeY = std::min( oldSizeY, VolumeProxy<T>::_sizeY );
749  int minSizeZ = std::min( oldSizeZ, VolumeProxy<T>::_sizeZ );
750  int minSizeT = std::min( oldSizeT, VolumeProxy<T>::_sizeT );
751 
752  // preserving data
753  int x, y, z, t;
754  if( newItems.allocatorContext().allocatorType()
755  != AllocatorStrategy::ReadOnlyMap )
756  for ( t = 0; t < minSizeT; t++ )
757  {
758 
759  for ( z = 0; z < minSizeZ; z++ )
760  {
761 
762  for ( y = 0; y < minSizeY; y++ )
763  {
764 
765  for ( x = 0; x < minSizeX; x++ )
766  {
767  newItems[ x +
769  z * ( size_t ) sizeXY +
770  t * ( size_t ) sizeXYZ ] =
771  _items[ x +
772  y * oldSizeX +
773  z * ( size_t ) oldSizeX
774  * ( size_t ) oldSizeY +
775  t * ( size_t ) oldSizeX *
776  ( size_t ) oldSizeY
777  * ( size_t ) oldSizeZ ];
778 
779  }
780 
781  }
782 
783  }
784 
785  }
786 
787  // copying new data to old one
788  _items = newItems;
789 
790  }
791 
792  if( allocate )
793  {
794 #ifdef CARTO_USE_BLITZ
795  // TODO: test blitz ownership / strides
796  /*
797  std::cout << "alloc blitz: " << VolumeProxy<T>::_sizeX << ", "
798  << VolumeProxy<T>::_sizeY << ", "
799  << VolumeProxy<T>::_sizeZ << ", "
800  << VolumeProxy<T>::_sizeT << std::endl;
801  */
802  _blitz.reference( blitz::Array<T,4>
803  ( &_items[0],
804  blitz::shape( VolumeProxy<T>::_sizeX,
808  blitz::GeneralArrayStorage<4>
809  ( blitz::shape( 0, 1, 2, 3 ), true ) ) );
810  /*
811  std::cout << &_items[0] << " / " << &_blitz( 0 ) << std::endl;
812  std::cout << blitz::shape( VolumeProxy<T>::_sizeX,
813  VolumeProxy<T>::_sizeY,
814  VolumeProxy<T>::_sizeZ,
815  VolumeProxy<T>::_sizeT ) << std::endl;
816  std::cout << "blitz data: " << _blitz.data() << std::endl;
817  std::cout << "blitz ordering: " << _blitz.ordering() << std::endl;
818  std::cout << "blitz numEl: " << _blitz.numElements() << std::endl;
819  std::cout << "blitz strides: " << _blitz.stride() << std::endl;
820  */
821 #else
822  _lineoffset = VolumeProxy<T>::_sizeX;
823  _sliceoffset = sizeXY;
824  _volumeoffset = sizeXYZ;
825 #endif
826  }
827  else
828  {
829 #ifdef CARTO_USE_BLITZ
830  // TODO: test blitz ownership / strides
831  _blitz.reference( blitz::Array<T,4>
832  ( 0,
833  blitz::shape( VolumeProxy<T>::_sizeX,
837  blitz::GeneralArrayStorage<4>
838  ( blitz::shape( 0, 1, 2, 3 ), true ) ) );
839 #else
840  _lineoffset = 0;
841  _sliceoffset = 0;
842  _volumeoffset = 0;
843 #endif
844  }
845 
846  }
847 
848 
849  template < typename T >
851  {
852  if( !allocatorContext().isAllocated() )
855  allocatorContext() );
856  }
857 
858 
859  template < typename T >
860  void Volume< T >::slotSizeChanged( const PropertyFilter& propertyFilter )
861  {
862 
863  std::cout << "Volume< " << DataTypeCode<T>::name()
864  << " >::slotSizeChanged"
865  << std::endl;
866 
867  int oldSizeX = VolumeProxy<T>::_sizeX;
868  int oldSizeY = VolumeProxy<T>::_sizeY;
869  int oldSizeZ = VolumeProxy<T>::_sizeZ;
870  int oldSizeT = VolumeProxy<T>::_sizeT;
871 
872  if ( propertyFilter.hasOldValue( "sizeX" ) )
873  {
874 
875  oldSizeX =
876  propertyFilter.getOldValue( "sizeX" )->GenericObject::value< int >();
877  std::cout << "old sizex: " << oldSizeX << std::endl;
878 
879  }
880  if ( propertyFilter.hasOldValue( "sizeY" ) )
881  {
882 
883  oldSizeY =
884  propertyFilter.getOldValue( "sizeY" )->GenericObject::value< int >();
885  std::cout << "old sizey: " << oldSizeY << std::endl;
886 
887  }
888  if ( propertyFilter.hasOldValue( "sizeZ" ) )
889  {
890 
891  oldSizeZ =
892  propertyFilter.getOldValue( "sizeZ" )->GenericObject::value< int >();
893  std::cout << "old sizez: " << oldSizeZ << std::endl;
894 
895  }
896  if ( propertyFilter.hasOldValue( "sizeT" ) )
897  {
898 
899  oldSizeT =
900  propertyFilter.getOldValue( "sizeT" )->GenericObject::value< int >();
901  std::cout << "old sizet: " << oldSizeT << std::endl;
902 
903  }
904  std::cout << "old size: " << oldSizeX << ", " << oldSizeY << ", "
905  << oldSizeZ << ", " << oldSizeT << std::endl;
906  std::cout << "new size: " << VolumeProxy<T>::_sizeX << ", "
907  << VolumeProxy<T>::_sizeY << ", "
909  << std::endl;
910  allocate( oldSizeX, oldSizeY, oldSizeZ, oldSizeT,
911  _items.allocatorContext().isAllocated(), allocatorContext() );
912 
913  }
914 
915 
916  template < typename T >
917  void Volume< T >::reallocate( int sizeX,
918  int sizeY,
919  int sizeZ,
920  int sizeT,
921  bool keepcontents,
922  const AllocatorContext & ac,
923  bool alloc )
924  {
925  int oldx = VolumeProxy<T>::_sizeX;
926  int oldy = VolumeProxy<T>::_sizeY;
927  int oldz = VolumeProxy<T>::_sizeZ;
928  int oldt = VolumeProxy<T>::_sizeT;
929  VolumeProxy<T>::_sizeX = sizeX;
930  VolumeProxy<T>::_sizeY = sizeY;
931  VolumeProxy<T>::_sizeZ = sizeZ;
932  VolumeProxy<T>::_sizeT = sizeT;
933  if( keepcontents || ( sizeX == oldx && sizeY == oldy && sizeZ == oldz
934  && sizeT == oldt ) )
935  allocate( oldx, oldy, oldz, oldt, alloc, ac );
936  else
937  allocate( -1, -1, -1, -1, alloc, ac );
938  // emit a signal ?
939  }
940 
941  template < typename T >
943  bool keepcontents,
944  const AllocatorContext & ac,
945  bool alloc )
946  {
947  return reallocate( size[0] > 0 ? size[0] : 1,
948  size[1] > 0 ? size[1] : 1,
949  size[2] > 0 ? size[2] : 1,
950  size[3] > 0 ? size[3] : 1,
951  keepcontents, ac, alloc );
952  }
953 
954 //============================================================================
955 // U T I L I T I E S
956 //============================================================================
957 
958  template <typename T>
959  Volume<T>* Creator<Volume<T> >::create( Object header,
960  const AllocatorContext & context,
961  Object options )
962  {
963  int sizex = 1, sizey = 1, sizez = 1, sizet = 1;
964  bool unalloc = false;
965  header->getProperty( "sizeX", sizex );
966  header->getProperty( "sizeY", sizey );
967  header->getProperty( "sizeZ", sizez );
968  header->getProperty( "sizeT", sizet );
969  options->getProperty( "unallocated", unalloc );
970  std::vector<int> borders( 3, 0 );
971  try {
972  borders[0] = (int) rint( options->getProperty( "border" )->getScalar() );
973  borders[1] = (int) rint( options->getProperty( "border" )->getScalar() );
974  borders[2] = (int) rint( options->getProperty( "border" )->getScalar() );
975  } catch( ... ) {}
976  try {
977  borders[0] = (int) rint( options->getProperty( "bx" )->getScalar() );
978  } catch( ... ) {}
979  try {
980  borders[1] = (int) rint( options->getProperty( "by" )->getScalar() );
981  } catch( ... ) {}
982  try {
983  borders[2] = (int) rint( options->getProperty( "bz" )->getScalar() );
984  } catch( ... ) {}
985  Volume<T> *obj;
986  if( borders[0] != 0 || borders[1] != 0 || borders[2] != 0 )
987  {
988  obj = new Volume<T>( sizex + borders[0] * 2,
989  sizey + borders[1] * 2,
990  sizez + borders[2] * 2,
991  sizet, context, !unalloc );
992  obj = new Volume<T>( rc_ptr<Volume<T> >( obj ),
993  typename Volume<T>::Position4Di( borders[0],
994  borders[1], borders[2], 0 ),
995  typename Volume<T>::Position4Di( sizex, sizey,
996  sizez, sizet ),
997  context );
998  }
999  else
1000  obj = new Volume<T>( sizex, sizey, sizez, sizet, context, !unalloc );
1001  obj->blockSignals( true );
1002  obj->header().copyProperties( header );
1003  // restore original sizes : temporary too...
1004  obj->blockSignals( false );
1005  return obj;
1006  }
1007 
1008  template <typename T>
1009  void Creator<Volume<T> >::setup( Volume<T> & obj, Object header,
1010  const AllocatorContext & context,
1011  Object options )
1012  {
1013  int sizex = 1, sizey = 1, sizez = 1, sizet = 1;
1014  bool unalloc = false, partial = false, keep_allocation = false;
1015  options->getProperty( "partial_reading", partial );
1016  if( !partial )
1017  {
1018  header->getProperty( "sizeX", sizex );
1019  header->getProperty( "sizeY", sizey );
1020  header->getProperty( "sizeZ", sizez );
1021  header->getProperty( "sizeT", sizet );
1022  options->getProperty( "unallocated", unalloc );
1023  options->getProperty( "keep_allocation", keep_allocation );
1024  if( !keep_allocation || !obj.allocatorContext().isAllocated() )
1025  obj.reallocate( sizex, sizey, sizez, sizet, false, context,
1026  !unalloc );
1027  }
1028  else
1029  {
1030  const_cast<AllocatorContext &>( obj.allocatorContext() ).setDataSource
1031  ( context.dataSource() );
1032  // preserve dimensions
1033  sizex = obj.getSizeX();
1034  sizey = obj.getSizeY();
1035  sizez = obj.getSizeZ();
1036  sizet = obj.getSizeT();
1037  }
1038  obj.blockSignals( true );
1039  obj.header().copyProperties( header );
1040  if( partial )
1041  {
1042  // restore dimensions
1043  PropertySet & ps = obj.header();
1044  ps.setProperty( "sizeX", sizex );
1045  ps.setProperty( "sizeY", sizey );
1046  ps.setProperty( "sizeZ", sizez );
1047  ps.setProperty( "sizeT", sizet );
1048  }
1049  obj.blockSignals( false );
1050  }
1051 
1052 } // namespace carto
1053 
1054 #endif // CARTODATA_VOLUME_VOLUMEBASE_D_H
Volume(int sizeX=1, int sizeY=1, int sizeZ=1, int sizeT=1, const AllocatorContext &allocatorContext=AllocatorContext(), bool allocated=true)
Volume construction and allocation.
Definition: volumebase_d.h:70
void setRefVolume(const rc_ptr< Volume< T > > &refvol)
Set parent volume.
Definition: volumebase_d.h:535
4D Volume main class
const Position4Di posInRefVolume() const
Get position in parent volume.
Definition: volumebase_d.h:451
void allocate()
This function is only useful in the particular context of an unallocated Volume, when the constructor...
Definition: volumebase_d.h:850
rc_ptr< Volume< T > > _refvol
Definition: volumebase.h:410
virtual bool getProperty(const std::string &key, Object &value) const =0
iterator begin()
Iterators returned here are the most "basic" (and fastest) iterators: they go from the first voxel li...
Definition: volumebase_d.h:621
bool hasOldValue(const std::string &propertyName) const
Object getOldValue(const std::string &propertyName) const
const AllocatorContext & allocatorContext() const
returns volume's AllocatorContext
Definition: volumebase_d.h:439
blitz::Array< T, 4 >::const_iterator const_iterator
Definition: volumebase.h:130
int getSizeT() const
Definition: volumeproxy.h:118
virtual void initialize()
const std::string & getName() const
VolumeProxy< T > & operator=(const VolumeProxy< T > &other)
Definition: volumeproxy_d.h:97
std::vector< size_t > getStrides() const
Get strides for the volume.
Definition: volumebase_d.h:562
void updateItemsBuffer()
Definition: volumebase_d.h:457
void setPosInRefVolume(const Position4Di &pos)
Set position in parent volume.
Definition: volumebase_d.h:527
VolumeProxy is the base class for volumes.
Definition: volumeproxy.h:49
std::string name()
blitz::Array< T, 4 > _blitz
Definition: volumebase.h:404
void addPropertyFilter(const rc_ptr< PropertyFilter > &propertyFilter)
bool signalsBlocked() const
const PropertySet & header() const
void setProperty(const std::string &, const T &)
T * get() const
int getSizeZ() const
Definition: volumeproxy.h:108
virtual void reallocate(int sizeX=1, int sizeY=1, int sizeZ=1, int sizeT=1, bool keepcontents=false, const AllocatorContext &allocatorContext=AllocatorContext(), bool allocate=true)
allows resizing and changing allocator
Definition: volumebase_d.h:917
rc_ptr< Volume< T > > refVolume() const
Get parent volume.
Definition: volumebase_d.h:445
int getSizeX() const
Definition: volumeproxy.h:88
blitz::Array< T, 4 >::iterator iterator
The most "basic" (and fastest) iterators: they go from the first voxel linerarly in memory...
Definition: volumebase.h:129
iterator end()
Definition: volumebase_d.h:634
std::vector< int > getBorders() const
Get borders for the volume.
Definition: volumebase_d.h:543
void constructBorders(const Position4Di &bordersize, const AllocatorContext &allocatorContext, bool allocated)
Definition: volumebase_d.h:109
bool connect(const std::string &propertyFilterName, const PropertyFilter::Slot &slot)
void blockSignals(bool)
Volume< T > & operator=(const Volume< T > &other)
Definition: volumebase_d.h:581
std::string toString(const T &object)
virtual void copyProperties(Object source)
Object none()
void slotSizeChanged(const PropertyFilter &propertyFilter)
Definition: volumebase_d.h:860
Position4Di _pos
Definition: volumebase.h:411
AllocatedVector< T > _items
Definition: volumebase.h:402
virtual void initialize()
Initializes header info.
Definition: volumebase_d.h:673
int getSizeY() const
Definition: volumeproxy.h:98
virtual ~Volume()
Definition: volumebase_d.h:430