cartodata  5.0.5
volumeutil.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_VOLUMEUTIL_H
35 #define CARTODATA_VOLUME_VOLUMEUTIL_H
36 
37 //--- cartodata --------------------------------------------------------------
40 //--- cartobase --------------------------------------------------------------
42 #include <cartobase/smart/rcptr.h>
43 //--- std --------------------------------------------------------------------
44 #include <algorithm>
45 #include <exception>
46 //----------------------------------------------------------------------------
47 
48 namespace carto
49 {
50 
51  //==========================================================================
52  //
53  // DECLARATIONS
54  //
55  //==========================================================================
56 
57  namespace volumeutil {
58 
59  //========================================================================
60  // Generic operators
61  //========================================================================
65 
69  template <typename T, typename UnaryFunction>
70  Volume<typename UnaryFunction::result_type>
71  apply( const Volume<T> & vol, UnaryFunction func );
72  template <typename T, typename U, typename BinaryFunction>
73  Volume<typename BinaryFunction::result_type>
74  apply( const Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func );
75  template <typename T, typename UnaryFunction>
76  rc_ptr<Volume<typename UnaryFunction::result_type> >
77  apply( const rc_ptr<Volume<T> > & vol, UnaryFunction func );
78  template <typename T, typename U, typename BinaryFunction>
79  rc_ptr<Volume<typename BinaryFunction::result_type> >
80  apply( const rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func );
81 
85  template <typename T, typename UnaryFunction>
86  Volume<T> & selfApply( Volume<T> & vol, UnaryFunction func );
87  template <typename T, typename U, typename BinaryFunction>
88  Volume<T> & selfApply( Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func );
89  template <typename T, typename UnaryFunction>
90  rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol, UnaryFunction func );
91  template <typename T, typename U, typename BinaryFunction>
92  rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func );
94 
101  template <typename T, typename OUTP, typename UnaryFunction>
102  Volume<OUTP> &
103  applyTowards( const Volume<T> & vol, Volume<OUTP> & dst, UnaryFunction func );
104  template <typename T, typename U, typename OUTP, typename BinaryFunction>
105  Volume<OUTP> &
106  applyTowards( const Volume<T> & vol1, const Volume<U> & vol2, Volume<OUTP> & dst, BinaryFunction func );
108 
122  template <typename OUTP, typename T, typename BinaryFunction>
123  OUTP accumulate( const Volume<T> & vol, BinaryFunction func, OUTP initial );
124  template <typename OUTP, typename T, typename BinaryFunction>
125  OUTP accumulate( const rc_ptr<Volume<T> > & vol, BinaryFunction func, OUTP initial );
127 
128  } // namespace volumeutil
129 
130  //==========================================================================
131  // Copy functions
132  //==========================================================================
133 
137  template <typename T>
138  void transfer( const Volume<T> & src, Volume<T> & dst );
139  template <typename T>
140  void transfer( const rc_ptr<Volume<T> > & src, rc_ptr<Volume<T> > & dst );
141  template <typename OUTP, typename INP>
142  void transfer( const Volume<INP> & src, Volume<OUTP> & dst );
143  template <typename OUTP, typename INP>
144  void transfer( const rc_ptr<Volume<INP> > & src, rc_ptr<Volume<OUTP> > & dst );
146 
150  template <typename T>
151  Volume<T> deepcopy( const Volume<T> & src );
152  template <typename T>
153  rc_ptr<Volume<T> > deepcopy( const rc_ptr<Volume<T> > & src );
154  template <typename OUTP, typename INP>
155  Volume<OUTP> deepcopy( const Volume<INP> & src );
156  template <typename OUTP, typename INP>
157  rc_ptr<Volume<OUTP> > deepcopy( const rc_ptr<Volume<INP> > & src );
159 
164  template <typename T>
165  Volume<T> copy( const Volume<T> & src );
166  template <typename T>
167  rc_ptr<Volume<T> > copy( const rc_ptr<Volume<T> > & src );
168  template <typename OUTP, typename INP>
169  Volume<OUTP> copy( const Volume<INP> & src );
170  template <typename OUTP, typename INP>
171  rc_ptr<Volume<OUTP> > copy( const rc_ptr<Volume<INP> > & src );
173 
176  template <typename T>
177  Volume<T> copyStructure( const Volume<T> & src );
178  template <typename T>
179  rc_ptr<Volume<T> > copyStructure( const rc_ptr<Volume<T> > & src );
180  template <typename OUTP, typename INP>
181  Volume<OUTP> copyStructure( const Volume<INP> & src );
182  template <typename OUTP, typename INP>
183  rc_ptr<Volume<OUTP> > copyStructure( const rc_ptr<Volume<INP> > & src );
185 
186  //==========================================================================
187  // Accumulated values: Min/Max/Sum...
188  //==========================================================================
189 
194  template <typename T>
195  T min( const Volume<T> & vol );
196  template <typename T>
197  T min( const rc_ptr<Volume<T> > & vol );
199 
204  template <typename T>
205  T max( const Volume<T> & vol );
206  template <typename T>
207  T max( const rc_ptr<Volume<T> > & vol );
209 
212  template <typename T>
213  typename DataTypeTraits<T>::LongType sum( const Volume<T> & vol );
214  template <typename OUTP, typename T>
215  OUTP sum( const Volume<T> & vol );
216  template <typename T>
217  typename DataTypeTraits<T>::LongType sum( const rc_ptr<Volume<T> > & vol );
218  template <typename OUTP, typename T>
219  OUTP sum( const rc_ptr<Volume<T> > & vol );
221 
224  template <typename T>
225  bool all( const Volume<T> & vol );
226  template <typename T>
227  bool all( const rc_ptr<Volume<T> > & vol );
229 
232  template <typename T>
233  bool any( const Volume<T> & vol );
234  template <typename T>
235  bool any( const rc_ptr<Volume<T> > & vol );
237 
238  //==========================================================================
239  // Special operators
240  //==========================================================================
241 
249  template <typename T, typename U>
250  Volume<bool> valuesIn( const Volume<T> & volume, const U & set );
251  template <typename T, typename U>
252  rc_ptr<Volume<bool> > valuesIn( const rc_ptr<Volume<T> > & volume, const U & set );
254 
262  template <typename T, typename U>
263  Volume<bool> valuesNotIn( const Volume<T> & volume, const U & set );
264  template <typename T, typename U>
265  rc_ptr<Volume<bool> > valuesNotIn( const rc_ptr<Volume<T> > & volume, const U & set );
267 
273  template <typename T, typename U>
274  void conditionalSet( Volume<T> & volume, const Volume<U> & condition, const T & value );
275  template <typename T, typename U>
276  void conditionalSet( rc_ptr<Volume<T> > & volume, const rc_ptr<Volume<U> > & condition, const T & value );
278 
283  template <typename T>
284  Volume<T> invertMinMax( const Volume<T> & volume );
285  template <typename T>
286  rc_ptr<Volume<T> > invertMinMax( const rc_ptr<Volume<T> > & volume );
288 
289  //==========================================================================
290  // Borders
291  //==========================================================================
292 
301  template <typename T>
302  void setBorders( Volume<T> & volume,
303  const typename Volume<T>::Position4Di & top,
304  const typename Volume<T>::Position4Di & bottom
305  = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
308  template <typename T>
309  void setBorders( rc_ptr<Volume<T> > & volume,
310  const typename Volume<T>::Position4Di & top,
311  const typename Volume<T>::Position4Di & bottom
312  = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
314 
322  template <typename T>
323  void setMinBorders( Volume<T> & volume,
324  const typename Volume<T>::Position4Di & top,
325  const typename Volume<T>::Position4Di & bottom
326  = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
329  template <typename T>
330  void setMinBorders( rc_ptr<Volume<T> > & volume,
331  const typename Volume<T>::Position4Di & top,
332  const typename Volume<T>::Position4Di & bottom
333  = typename Volume<T>::Position4Di(-1, -1, -1, -1) );
335 
336 
337  //==========================================================================
338  //
339  // DEFINITIONS
340  //
341  //==========================================================================
342 
343  namespace volumeutil {
344 
345  //========================================================================
346  // Generic operators
347  //========================================================================
348 
349  //--- Volume [op] other --------------------------------------------------
350 
351  template <typename T, typename UnaryFunction>
352  Volume<typename UnaryFunction::result_type>
353  apply( const Volume<T> & vol, UnaryFunction func )
354  {
355  typedef typename UnaryFunction::result_type OUTP;
356  Volume<OUTP> output = deepcopy<OUTP,T>(vol);
357  applyTowards( vol, output, func );
358  return output;
359  }
360 
361  template <typename T, typename U, typename BinaryFunction>
363  apply( const Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func )
364  {
365  typedef typename BinaryFunction::result_type OUTP;
366  Volume<OUTP> output = deepcopy<OUTP,T>(vol1);
367  applyTowards( vol1, vol2, output, func );
368  return output;
369  }
370 
371  //--- VolumeRef [op]= other ----------------------------------------------
372 
373  template <typename T, typename UnaryFunction>
375  apply( const rc_ptr<Volume<T> > & vol, UnaryFunction func )
376  {
377  typedef typename UnaryFunction::result_type OUTP;
378  rc_ptr<Volume<OUTP> > output = deepcopy<OUTP,T>(vol);
379  applyTowards( *vol, *output, func );
380  return output;
381  }
382 
383  template <typename T, typename U, typename BinaryFunction>
385  apply( const rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func )
386  {
387  typedef typename BinaryFunction::result_type OUTP;
388  rc_ptr<Volume<OUTP> > output = deepcopy<OUTP,T>(vol1);
389  applyTowards( *vol1, vol2, *output, func );
390  return output;
391  }
392 
393  //--- Volume [op]= other -------------------------------------------------
394 
395  template <typename T, typename UnaryFunction>
396  Volume<T> & selfApply( Volume<T> & vol, UnaryFunction func )
397  {
398  applyTowards( vol, vol, func );
399  return vol;
400  }
401 
402  template <typename T, typename U, typename BinaryFunction>
403  Volume<T> & selfApply( Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func )
404  {
405  applyTowards( vol1, vol2, vol1, func );
406  return vol1;
407  }
408 
409  //--- VolumeRef [op]= other ----------------------------------------------
410 
411  template <typename T, typename UnaryFunction>
412  rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol, UnaryFunction func )
413  {
414  selfApply( *vol, func );
415  return vol;
416  }
417 
418  template <typename T, typename U, typename BinaryFunction>
419  rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func )
420  {
421  selfApply( *vol1, vol2, func );
422  return vol1;
423  }
424 
425  //--- Volume [op] other -> Output ---------------------------------------
426  template <typename T, typename OUTP, typename UnaryFunction>
427  Volume<OUTP> &
428  applyTowards( const Volume<T> & vol, Volume<OUTP> & dst, UnaryFunction func )
429  {
430  for( long t = 0; t < vol.getSizeT(); ++t )
431  for( long z = 0; z < vol.getSizeZ(); ++z )
432  for( long y = 0; y < vol.getSizeY(); ++y )
433  for( long x = 0; x < vol.getSizeX(); ++x )
434  dst( x, y, z, t ) = func( vol( x, y, z, t ) );
435  return dst;
436  }
437 
438  template <typename T, typename U, typename OUTP, typename BinaryFunction>
439  Volume<OUTP> &
440  applyTowards( const Volume<T> & vol1, const Volume<U> & vol2, Volume<OUTP> & dst, BinaryFunction func )
441  {
442  for( long t = 0; t < vol1.getSizeT() && t < vol2.getSizeT(); ++t )
443  for( long z = 0; z < vol1.getSizeZ() && z < vol2.getSizeZ(); ++z )
444  for( long y = 0; y < vol1.getSizeY() && y < vol2.getSizeY(); ++y )
445  for( long x = 0; x < vol1.getSizeX() && x < vol2.getSizeX(); ++x )
446  dst( x, y, z, t ) = func( vol1( x, y, z, t ), vol2( x, y, z, t ) );
447  return dst;
448  }
449 
450  //--- Volume: accumulate -------------------------------------------------
451 
452  template <typename OUTP, typename T, typename BinaryFunction>
453  OUTP accumulate( const Volume<T> & vol, BinaryFunction func, OUTP initial )
454  {
455  for( long t = 0; t < vol.getSizeT(); ++t )
456  for( long z = 0; z < vol.getSizeZ(); ++z )
457  for( long y = 0; y < vol.getSizeY(); ++y )
458  for( long x = 0; x < vol.getSizeX(); ++x )
459  initial = func( initial, vol( x, y, z, t ) );
460  return initial;
461  }
462 
463  //--- VolumeRef: accumulate ----------------------------------------------
464 
465  template <typename OUTP, typename T, typename BinaryFunction>
466  OUTP accumulate( const rc_ptr<Volume<T> > & vol, BinaryFunction func, OUTP initial )
467  {
468  return accumulate<OUTP, T, BinaryFunction>( *vol, func, initial );
469  }
470 
471  } // namespace volumeutil
472 
473  //==========================================================================
474  // Copy functions
475  //==========================================================================
476 
477  //--- transfer -------------------------------------------------------------
478 
479  template <typename T>
480  void transfer( const Volume<T> & src, Volume<T> & dst )
481  {
482  transfer<T,T>( src, dst );
483  }
484 
485  template <typename T>
486  void transfer( const rc_ptr<Volume<T> > & src, rc_ptr<Volume<T> > & dst )
487  {
488  transfer<T,T>( src, dst );
489  }
490 
491  template <typename OUTP, typename INP>
492  void transfer( const Volume<INP> & src, Volume<OUTP> & dst )
493  {
495  }
496 
497  template <typename OUTP, typename INP>
498  void transfer( const rc_ptr<Volume<INP> > & src, rc_ptr<Volume<OUTP> > & dst )
499  {
500  transfer( *src, *dst );
501  }
502 
503  //--- deepcopy -------------------------------------------------------------
504 
505  template <typename T>
506  Volume<T> deepcopy( const Volume<T> & src )
507  {
508  return deepcopy<T,T>( src );
509  }
510 
511  template <typename T>
513  {
514  return deepcopy<T,T>( src );
515  }
516 
517  template <typename OUTP, typename INP>
519  {
520  Volume<OUTP> dst( src.getSizeX(), src.getSizeY(),
521  src.getSizeZ(), src.getSizeT(),
522  src.allocatorContext(),
523  src.allocatorContext().isAllocated() );
524  dst.copyHeaderFrom( src.header() );
525  if( src.allocatorContext().isAllocated() )
526  transfer( src, dst );
527 
528  if( src.refVolume() )
529  {
530  rc_ptr<Volume<INP> > srcparent = src.refVolume();
531  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
532  srcparent->getSizeX(), srcparent->getSizeY(),
533  srcparent->getSizeZ(), srcparent->getSizeT(),
534  srcparent->allocatorContext(),
535  srcparent->allocatorContext().isAllocated() ) );
536  if( srcparent->allocatorContext().isAllocated() )
537  transfer( srcparent, dstparent );
538  dst.setRefVolume( dstparent );
539  dst.setPosInRefVolume( src.posInRefVolume() );
540  }
541 
542  rc_ptr<Volume<INP> > srcchild = src.refVolume();
543  rc_ptr<Volume<OUTP> > dstchild = dst.refVolume();
544 
545  while( srcchild->refVolume().get() )
546  {
547  rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
548  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
549  srcparent->getSizeX(), srcparent->getSizeY(),
550  srcparent->getSizeZ(), srcparent->getSizeT(),
551  srcparent->allocatorContext(),
552  srcparent->allocatorContext().isAllocated() ) );
553  dstparent->copyHeaderFrom( srcparent->header() );
554  if( srcparent->allocatorContext().isAllocated() )
555  transfer( srcparent, dstparent );
556  dstchild->setRefVolume( dstparent );
557  dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
558  srcchild = srcparent;
559  dstchild = dstparent;
560  }
561 
562  return dst;
563  }
564 
565  template <typename OUTP, typename INP>
567  {
569  src->getSizeX(), src->getSizeY(),
570  src->getSizeZ(), src->getSizeT(),
571  src->allocatorContext(),
572  src->allocatorContext().isAllocated() ) );
573  dst->copyHeaderFrom( src->header() );
574  if( src->allocatorContext().isAllocated() )
575  transfer( src, dst );
576 
577  rc_ptr<Volume<INP> > srcchild = src;
578  rc_ptr<Volume<OUTP> > dstchild = dst;
579 
580  while( srcchild->refVolume().get() )
581  {
582  rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
583  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
584  srcparent->getSizeX(), srcparent->getSizeY(),
585  srcparent->getSizeZ(), srcparent->getSizeT(),
586  srcparent->allocatorContext(),
587  srcparent->allocatorContext().isAllocated() ) );
588  dstparent->copyHeaderFrom( srcparent->header() );
589  if( srcparent->allocatorContext().isAllocated() )
590  transfer( srcparent, dstparent );
591  dstchild->setRefVolume( dstparent );
592  dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
593  srcchild = srcparent;
594  dstchild = dstparent;
595  }
596 
597  return dst;
598  }
599 
600 
601  //--- copy -----------------------------------------------------------------
602 
603  template <typename T>
604  Volume<T> copy( const Volume<T> & src )
605  {
606  return copy<T,T>( src );
607  }
608 
609  template <typename T>
611  {
612  return copy<T,T>( src );
613  }
614 
615  template <typename OUTP, typename INP>
617  {
618  Volume<OUTP> dst( src.getSizeX(), src.getSizeY(),
619  src.getSizeZ(), src.getSizeT() );
620  dst.copyHeaderFrom( src.header() );
621  transfer( src, dst );
622  return dst;
623  }
624 
625  template <typename OUTP, typename INP>
627  {
629  src->getSizeX(), src->getSizeY(),
630  src->getSizeZ(), src->getSizeT() ) );
631  dst->copyHeaderFrom( src->header() );
632  transfer( src, dst );
633  return dst;
634  }
635 
636 
637  //--- copyStructure --------------------------------------------------------
638 
639  template <typename T>
641  {
642  return copyStructure<T,T>( src );
643  }
644 
645  template <typename T>
647  {
648  return copyStructure<T,T>( src );
649  }
650 
651  template <typename OUTP, typename INP>
653  {
654  Volume<OUTP> dst( src.getSizeX(), src.getSizeY(),
655  src.getSizeZ(), src.getSizeT(),
656  src.allocatorContext(),
657  src.allocatorContext().isAllocated() );
658  dst.copyHeaderFrom( src.header() );
659  // if( src.allocatorContext().isAllocated() )
660  // dst.fill(0);
661 
662  if( src.refVolume() )
663  {
664  rc_ptr<Volume<INP> > srcparent = src.refVolume();
665  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
666  srcparent->getSizeX(), srcparent->getSizeY(),
667  srcparent->getSizeZ(), srcparent->getSizeT(),
668  srcparent->allocatorContext(),
669  srcparent->allocatorContext().isAllocated() ) );
670  // if( srcparent->allocatorContext().isAllocated() )
671  // dstparent->fill(0);
672  dst.setRefVolume( dstparent );
673  dst.setPosInRefVolume( src.posInRefVolume() );
674 
675  rc_ptr<Volume<INP> > srcchild = src.refVolume();
676  rc_ptr<Volume<OUTP> > dstchild = dst.refVolume();
677 
678  while( srcchild->refVolume().get() )
679  {
680  rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
681  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
682  srcparent->getSizeX(), srcparent->getSizeY(),
683  srcparent->getSizeZ(), srcparent->getSizeT(),
684  srcparent->allocatorContext(),
685  srcparent->allocatorContext().isAllocated() ) );
686  dstparent->copyHeaderFrom( srcparent->header() );
687  // if( srcparent->allocatorContext().isAllocated() )
688  // dstparent->fill(0);
689  dstchild->setRefVolume( dstparent );
690  dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
691  srcchild = srcparent;
692  dstchild = dstparent;
693  }
694 
695  }
696 
697  return dst;
698  }
699 
700  template <typename OUTP, typename INP>
702  {
703  if( !src.get() )
704  return rc_ptr<Volume<OUTP> >( (Volume<OUTP>*)0 );
705 
707  src->getSizeX(), src->getSizeY(),
708  src->getSizeZ(), src->getSizeT(),
709  src->allocatorContext(),
710  src->allocatorContext().isAllocated() ) );
711  dst->copyHeaderFrom( src->header() );
712  // if( src->allocatorContext().isAllocated() )
713  // dst->fill(0);
714 
715  rc_ptr<Volume<INP> > srcchild = src;
716  rc_ptr<Volume<OUTP> > dstchild = dst;
717 
718  while( srcchild->refVolume().get() )
719  {
720  rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
721  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
722  srcparent->getSizeX(), srcparent->getSizeY(),
723  srcparent->getSizeZ(), srcparent->getSizeT(),
724  srcparent->allocatorContext(),
725  srcparent->allocatorContext().isAllocated() ) );
726  dstparent->copyHeaderFrom( srcparent->header() );
727  // if( srcparent->allocatorContext().isAllocated() )
728  // dstparent->fill(0);
729  dstchild->setRefVolume( dstparent );
730  dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
731  srcchild = srcparent;
732  dstchild = dstparent;
733  }
734 
735  return dst;
736  }
737 
738 
739  //==========================================================================
740  // Min/Max/Sum/Any/All
741  //==========================================================================
742 
743  template <typename T>
744  T min( const Volume<T> & vol )
745  {
746  if( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
747  vol.getSizeZ() == 0 && vol.getSizeT() == 0 )
748  throw std::runtime_error("Cannot compute min of an empty volume");
749  return accumulate( vol, volumeutil::select_min<T>(), vol.at(0, 0, 0, 0) );
750  }
751 
752  template <typename T>
753  T min( const rc_ptr<Volume<T> > & vol )
754  {
755  if( !vol.get() || ( vol->getSizeX() == 0 && vol->getSizeY() == 0 &&
756  vol->getSizeZ() == 0 && vol->getSizeT() == 0 ) )
757  throw std::runtime_error("Cannot compute min of an empty volume");
758  return accumulate( vol, volumeutil::select_min<T>(), vol->at(0, 0, 0, 0) );
759  }
760 
761  template <typename T>
762  T max( const Volume<T> & vol )
763  {
764  if( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
765  vol.getSizeZ() == 0 && vol.getSizeT() == 0 )
766  throw std::runtime_error("Cannot compute max of an empty volume");
767  return accumulate( vol, volumeutil::select_max<T>(), vol.at(0, 0, 0, 0) );
768  }
769 
770  template <typename T>
771  T max( const rc_ptr<Volume<T> > & vol )
772  {
773  if( !vol.get() || ( vol->getSizeX() == 0 && vol->getSizeY() == 0 &&
774  vol->getSizeZ() == 0 && vol->getSizeT() == 0 ) )
775  throw std::runtime_error("Cannot compute max of an empty volume");
776  return accumulate( vol, volumeutil::select_max<T>(), vol->at(0, 0, 0, 0) );
777  }
778 
779  template <typename T>
780  typename DataTypeTraits<T>::LongType sum( const Volume<T> & vol )
781  {
782  return sum<typename DataTypeTraits<T>::LongType,T>( vol );
783  }
784 
785 
786  template <typename OUTP, typename T>
787  OUTP sum( const Volume<T> & vol )
788  {
789  return accumulate( vol, volumeutil::plus<OUTP,T>(), static_cast<OUTP>(0) );
790  }
791 
792  template <typename T>
794  {
795  return sum<typename DataTypeTraits<T>::LongType,T>( vol );
796  }
797 
798  template <typename OUTP, typename T>
799  OUTP sum( const rc_ptr<Volume<T> > & vol )
800  {
801  if( !vol.get() )
802  return static_cast<OUTP>(0);
803  return accumulate( vol, volumeutil::plus<OUTP,T>(), static_cast<OUTP>(0) );
804  }
805 
806  template <typename T>
807  bool all( const Volume<T> & vol )
808  {
810  }
811 
812  template <typename T>
813  bool all( const rc_ptr<Volume<T> > & vol )
814  {
816  }
817 
818  template <typename T>
819  bool any( const Volume<T> & vol )
820  {
822  }
823 
824  template <typename T>
825  bool any( const rc_ptr<Volume<T> > & vol )
826  {
828  }
829 
830  //==========================================================================
831  // Special operators
832  //==========================================================================
833 
834  namespace internal {
835  template <typename T, typename U>
836  struct inSet: public std::binary_function<T, U, bool>
837  {
838  bool operator() ( const T & x, const U & y )
839  {
840  for( typename U::const_iterator k = y.begin(); k != y.end(); ++k )
841  if( x == *k )
842  return true;
843  return false;
844  }
845  };
846  } // namespace internal
847 
848  template <typename T, typename U>
849  Volume<bool> valuesIn( const Volume<T> & volume, const U & set )
850  {
851  Volume<bool> output = copyStructure<bool, T>( volume );
852  volumeutil::applyTowards( volume, output, std::bind2nd( internal::inSet<T,U>(), set ) );
853  return output;
854  }
855 
856  template <typename T, typename U>
857  rc_ptr<Volume<bool> > valuesIn( const rc_ptr<Volume<T> > & volume, const U & set )
858  {
859  rc_ptr<Volume<bool> > output = copyStructure<bool, T>( volume );
860  volumeutil::applyTowards( *volume, *output, std::bind2nd( internal::inSet<T,U>(), set ) );
861  return output;
862  }
863 
864  namespace internal {
865  template <typename T, typename U>
866  struct notInSet: public std::binary_function<T, U, bool>
867  {
868  bool operator() ( const T & x, const U & y )
869  {
870  for( typename U::const_iterator k = y.begin(); k != y.end(); ++k )
871  if( x == *k )
872  return false;
873  return true;
874  }
875  };
876  } // namespace internal
877 
878  template <typename T, typename U>
879  Volume<bool> valuesNotIn( const Volume<T> & volume, const U & set )
880  {
881  Volume<bool> output = copyStructure<bool, T>( volume );
882  volumeutil::applyTowards( volume, output, std::bind2nd( internal::notInSet<T,U>(), set ) );
883  return output;
884  }
885 
886  template <typename T, typename U>
887  rc_ptr<Volume<bool> > valuesNotIn( const rc_ptr<Volume<T> > & volume, const U & set )
888  {
889  rc_ptr<Volume<bool> > output = copyStructure<bool, T>( volume );
890  volumeutil::applyTowards( *volume, *output, std::bind2nd( internal::notInSet<T,U>(), set ) );
891  return output;
892  }
893 
894  namespace internal {
895  template <typename T, typename U>
896  struct changeIf: public std::binary_function<T, U, T>
897  {
898  changeIf( const T & value ): _value(value) {}
899  bool operator() ( const T & x, const U & y )
900  {
901  return y ? _value : x;
902  }
903  private:
904  T _value;
905  };
906  } // namespace internal
907 
908  template <typename T, typename U>
909  void conditionalSet( Volume<T> & volume, const Volume<U> & condition, const T & value )
910  {
911  volumeutil::selfApply( volume, condition, internal::changeIf<T,U>(value) );
912  }
913 
914  template <typename T, typename U>
915  void conditionalSet( rc_ptr<Volume<T> > & volume, const rc_ptr<Volume<U> > & condition, const T & value )
916  {
917  volumeutil::selfApply( volume, *condition, internal::changeIf<T,U>(value) );
918  }
919 
920  namespace internal {
921  template <typename T>
922  struct invMinMax: public std::unary_function<T, T>
923  {
924  invMinMax( const T & min, const T & max ):
925  _min(min),
926  _max(max)
927  {}
928 
929  T operator() ( const T & x )
930  {
931  return max - x + min;
932  }
933  private:
934  T _min;
935  T _max;
936  };
937  } // namespace internal
938 
939  template <typename T>
940  Volume<T> invertMinMax( const Volume<T> & volume )
941  {
942  T min = min( volume );
943  T max = max( volume );
944  volumeutil::apply( volume, internal::invMinMax<T>(min, max) );
945  }
946 
947  template <typename T>
949  {
950  T min = min( volume );
951  T max = max( volume );
952  volumeutil::apply( volume, internal::invMinMax<T>(min, max) );
953  }
954 
955  //==========================================================================
956  // Borders
957  //==========================================================================
958 
959  template <typename T>
960  void setBorders( Volume<T> & volume,
961  const typename Volume<T>::Position4Di & top,
962  const typename Volume<T>::Position4Di & bottom )
963  {
964  const typename Volume<T>::Position4Di & bot =
965  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
966  top : bottom );
967  std::vector<int> b = volume.getBorders();
968  if( b[0] != top[0] || b[1] != bot[0] ||
969  b[2] != top[1] || b[3] != bot[1] ||
970  b[4] != top[2] || b[5] != bot[2] ||
971  b[6] != top[3] || b[7] != bot[3] )
972  {
973  rc_ptr<Volume<T> > parent( new Volume<T>(
974  volume.getSizeX() + top[0] + bot[0],
975  volume.getSizeY() + top[1] + bot[1],
976  volume.getSizeZ() + top[2] + bot[2],
977  volume.getSizeT() + top[3] + bot[3] ) );
978  parent->copyHeaderFrom( volume.header() );
979  typename Volume<T>::Position4Di size( volume.getSizeX(),
980  volume.getSizeY(),
981  volume.getSizeZ(),
982  volume.getSizeT() );
983  Volume<T> view( parent, top, size );
984  transfer( volume, view );
985  volume.reallocate( volume.getSizeX(), volume.getSizeY(),
986  volume.getSizeZ(), volume.getSizeT(),
987  true, volume.allocatorContext(), false );
988  volume.setRefVolume( parent );
989  volume.setPosInRefVolume( top );
990  }
991  }
992 
993  template <typename T>
994  void setBorders( rc_ptr<Volume<T> > & volume,
995  const typename Volume<T>::Position4Di & top,
996  const typename Volume<T>::Position4Di & bottom )
997  {
998  const typename Volume<T>::Position4Di & bot =
999  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1000  top : bottom );
1001  std::vector<int> b = volume->getBorders();
1002  if( b[0] != top[0] || b[1] != bot[0] ||
1003  b[2] != top[1] || b[3] != bot[1] ||
1004  b[4] != top[2] || b[5] != bot[2] ||
1005  b[6] != top[3] || b[7] != bot[3] )
1006  {
1007  rc_ptr<Volume<T> > parent( new Volume<T>(
1008  volume->getSizeX() + top[0] + bot[0],
1009  volume->getSizeY() + top[1] + bot[1],
1010  volume->getSizeZ() + top[2] + bot[2],
1011  volume->getSizeT() + top[3] + bot[3] ) );
1012  parent->copyHeaderFrom( volume->header() );
1013  typename Volume<T>::Position4Di size( volume->getSizeX(),
1014  volume->getSizeY(),
1015  volume->getSizeZ(),
1016  volume->getSizeT() );
1017  rc_ptr<Volume<T> > view( new Volume<T>( parent, top, size ) );
1018  transfer( volume, view );
1019  volume->reallocate( volume->getSizeX(), volume->getSizeY(),
1020  volume->getSizeZ(), volume->getSizeT(),
1021  true, volume->allocatorContext(), false );
1022  volume->setRefVolume( parent );
1023  volume->setPosInRefVolume( top );
1024  }
1025  }
1026 
1027  template <typename T>
1028  void setMinBorders( Volume<T> & volume,
1029  const typename Volume<T>::Position4Di & top,
1030  const typename Volume<T>::Position4Di & bottom )
1031  {
1032  const typename Volume<T>::Position4Di & bot =
1033  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1034  top : bottom );
1035  std::vector<int> b = volume.getBorders();
1036  if( b[0] < top[0] || b[1] < bot[0] ||
1037  b[2] < top[1] || b[3] < bot[1] ||
1038  b[4] < top[2] || b[5] < bot[2] ||
1039  b[6] < top[3] || b[7] < bot[3] )
1040  {
1041  rc_ptr<Volume<T> > parent( new Volume<T>(
1042  volume.getSizeX() + top[0] + bot[0],
1043  volume.getSizeY() + top[1] + bot[1],
1044  volume.getSizeZ() + top[2] + bot[2],
1045  volume.getSizeT() + top[3] + bot[3] ) );
1046  parent->copyHeaderFrom( volume.header() );
1047  typename Volume<T>::Position4Di size( volume.getSizeX(),
1048  volume.getSizeY(),
1049  volume.getSizeZ(),
1050  volume.getSizeT() );
1051  Volume<T> view( parent, top, size );
1052  transfer( volume, view );
1053  volume.reallocate( volume.getSizeX(), volume.getSizeY(),
1054  volume.getSizeZ(), volume.getSizeT(),
1055  true, volume.allocatorContext(), false );
1056  volume.setRefVolume( parent );
1057  volume.setPosInRefVolume( top );
1058  }
1059  }
1060 
1061  template <typename T>
1062  void setMinBorders( rc_ptr<Volume<T> > & volume,
1063  const typename Volume<T>::Position4Di & top,
1064  const typename Volume<T>::Position4Di & bottom )
1065  {
1066  const typename Volume<T>::Position4Di & bot =
1067  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1068  top : bottom );
1069  std::vector<int> b = volume->getBorders();
1070  if( b[0] < top[0] || b[1] < bot[0] ||
1071  b[2] < top[1] || b[3] < bot[1] ||
1072  b[4] < top[2] || b[5] < bot[2] ||
1073  b[6] < top[3] || b[7] < bot[3] )
1074  {
1075  rc_ptr<Volume<T> > parent( new Volume<T>(
1076  volume->getSizeX() + top[0] + bot[0],
1077  volume->getSizeY() + top[1] + bot[1],
1078  volume->getSizeZ() + top[2] + bot[2],
1079  volume->getSizeT() + top[3] + bot[3] ) );
1080  parent->copyHeaderFrom( volume->header() );
1081  typename Volume<T>::Position4Di size( volume->getSizeX(),
1082  volume->getSizeY(),
1083  volume->getSizeZ(),
1084  volume->getSizeT() );
1085  rc_ptr<Volume<T> > view( new Volume<T>( parent, top, size ) );
1086  transfer( volume, view );
1087  volume->reallocate( volume->getSizeX(), volume->getSizeY(),
1088  volume->getSizeZ(), volume->getSizeT(),
1089  true, volume->allocatorContext(), false );
1090  volume->setRefVolume( parent );
1091  volume->setPosInRefVolume( top );
1092  }
1093  }
1094 
1095  //==========================================================================
1096  //
1097  // OLD CLASSES / METHODS
1098  //
1099  //==========================================================================
1100  template <typename T> class VolumeRef;
1101 
1102 
1108  template <typename T, class BinaryFunction>
1110  {
1111  public:
1112  inline UnaryFromConstantBinaryFunctor( const T & x, BinaryFunction func )
1113  : value( x ), f( func ) {}
1114  inline T operator () ( const T & y ) const
1115  { return f( y, value ); }
1117  BinaryFunction f;
1118  };
1119 
1120 
1125  template <typename T, class BinaryFunction>
1127  {
1128  public:
1129  inline UnaryFromConstantBinaryFunctor2( const T & x, BinaryFunction func )
1130  : value( x ), f( func ) {}
1131  inline T operator () ( const T & y ) const
1132  { return f( value, y ); }
1134  BinaryFunction f;
1135  };
1140  template <typename T, typename U>
1141  class Scaler
1142  {
1143  public:
1144  inline Scaler( U x ) : scale( x ) {}
1145  inline T operator () ( const T & x ) const
1146  { return (T) ( x * scale ); }
1148  };
1149 
1150  template<> inline cfloat
1152  {
1153  return x * (float) scale;
1154  }
1155 
1156  template<> inline cfloat
1158  {
1159  return x * (float) scale;
1160  }
1161 
1162  template<> inline cdouble
1164  {
1165  return x * (double) scale;
1166  }
1167 
1168  template<> inline cdouble
1170  {
1171  return x * (double) scale;
1172  }
1173 
1178  template <typename T, typename U>
1179  class Divider
1180  {
1181  public:
1182  inline Divider( U x ) : divisor( x ) {}
1183  inline T operator () ( const T & x ) const
1184  { return (T) ( x / divisor ); }
1186  };
1187 
1188  template<> inline cfloat
1190  {
1191  return x * (float) ( 1. / divisor );
1192  }
1193 
1194  template<> inline cfloat
1196  {
1197  return x * (float) ( 1. / (double) divisor );
1198  }
1199 
1200  template<> inline cdouble
1202  {
1203  return x * ( 1. / divisor );
1204  }
1205 
1206  template<> inline cdouble
1208  {
1209  return x * (double) ( 1. / divisor );
1210  }
1211 
1212  template<> inline cdouble
1214  {
1215  return x * (double) ( 1. / divisor );
1216  }
1217 
1218  template <typename T, bool Scalar>
1220  };
1221 
1223  template <typename T>
1224  class VolumeUtilBase<T, true> {
1225  public :
1228  static T min( const Volume<T> & o );
1229 
1232  static T max( const Volume<T> & o );
1233  };
1234 
1236  template <typename T>
1237  class VolumeUtilBase<T, false> {
1238  };
1239 
1241  template <typename T>
1242  class VolumeUtil: public carto::VolumeUtilBase<T, carto::DataTypeTraits<T>::is_scalar>
1243  {
1244  public:
1246  template <class UnaryFunction> static
1247  VolumeRef<T> apply( UnaryFunction f, const VolumeRef<T> & o );
1249  template <class BinaryFunction> static
1250  VolumeRef<T> apply( BinaryFunction f, const VolumeRef<T> & o1,
1251  const VolumeRef<T> & o2 );
1254  template <class UnaryFunction> static
1255  void selfApply( UnaryFunction f, VolumeRef<T> & o );
1258  template <class BinaryFunction> static
1259  void selfApply( BinaryFunction f, VolumeRef<T> & o1,
1260  const VolumeRef<T> & o2 );
1271  template <class BinaryFunction> static
1272  T accumulate( BinaryFunction f, const VolumeRef<T> & o2, T initial )
1273  { return accumulate( f, *o2, initial ); }
1274  template <class BinaryFunction> static
1275  T accumulate( BinaryFunction f, const Volume<T> & o2, T initial );
1276  };
1277 
1278 } // namespace carto
1279 
1280 #endif // CARTODATA_VOLUME_VOLUMEUTIL_H
1281 
void setRefVolume(const rc_ptr< Volume< T > > &refvol)
Set parent volume.
Definition: volumebase_d.h:779
Volume< T > copyStructure(const Volume< T > &src)
Performs a copy of the view structure without transfering the data.
Definition: volumeutil.h:640
const Position & posInRefVolume() const
Get position in parent volume.
Definition: volumebase_d.h:607
N-D Volume main class.
Volume< T > & selfApply(Volume< T > &vol, UnaryFunction func)
Apply a function to all the elements of a volume (in place version)
Definition: volumeutil.h:396
int getSizeZ() const
Definition: volumeproxy.h:107
const T & at(long x, long y=0, long z=0, long t=0) const
bool any(const Volume< T > &vol)
Returns true if at least one value compares to true.
Definition: volumeutil.h:819
T operator()(const T &x) const
Definition: volumeutil.h:1145
void conditionalSet(Volume< T > &volume, const Volume< U > &condition, const T &value)
Conditionally fill a volume.
Definition: volumeutil.h:909
T max(const Volume< T > &vol)
Returns the maximum value of the volume.
Definition: volumeutil.h:762
DataTypeTraits< T >::LongType sum(const Volume< T > &vol)
Returns the sum of the volume values.
Definition: volumeutil.h:780
Divider functor.
Definition: volumeutil.h:1179
Convenient handle for a Volume - this is normally the entry point for all volumes handling...
T operator()(const T &x) const
Definition: volumeutil.h:1183
void setMinBorders(Volume< T > &volume, const typename Volume< T >::Position4Di &top, const typename Volume< T >::Position4Di &bottom=typename Volume< T >::Position4Di(-1, -1, -1, -1))
Set border width.
Definition: volumeutil.h:1028
void setPosInRefVolume(const Position4Di &pos)
Set position in parent volume.
Definition: volumebase_d.h:757
invMinMax(const T &min, const T &max)
Definition: volumeutil.h:924
Scaler functor.
Definition: volumeutil.h:1141
const AllocatorContext & allocatorContext() const
returns volume&#39;s AllocatorContext
Definition: volumebase_d.h:595
int getSizeX() const
Definition: volumeproxy.h:87
std::complex< float > cfloat
T min(const Volume< T > &vol)
Returns the minimum value of the volume.
Definition: volumeutil.h:744
virtual void copyHeaderFrom(const PropertySet &other)
copy properties from other to this, avoiding forbidden properties like size.
Definition: volumeproxy.h:137
UnaryFromConstantBinaryFunctor2(const T &x, BinaryFunction func)
Definition: volumeutil.h:1129
std::vector< int > getBorders() const
Get borders for the volume.
Definition: volumebase_d.h:787
void transfer(const Volume< T > &src, Volume< T > &dst)
Transfer data from an allocated volume to another Allocated sizes must be equal (same number of voxel...
Definition: volumeutil.h:480
Volume utilities classes.
Definition: volumeutil.h:1242
Volume< bool > valuesNotIn(const Volume< T > &volume, const U &set)
Find values not contained in a set.
Definition: volumeutil.h:879
UnaryFromConstantBinaryFunctor(const T &x, BinaryFunction func)
Definition: volumeutil.h:1112
rc_ptr< Volume< T > > refVolume() const
Get parent volume.
Definition: volumebase_d.h:601
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
Volume< T > copy(const Volume< T > &src)
Performs a copy of the data (not only a reference copy) Only the data inside the view is copied...
Definition: volumeutil.h:604
Volume< T > deepcopy(const Volume< T > &src)
Performs a copy of the data (not only a reference copy) The whole view hierarchy is fully duplicated...
Definition: volumeutil.h:506
bool all(const Volume< T > &vol)
Returns true if all values compare to true.
Definition: volumeutil.h:807
void setBorders(Volume< T > &volume, const typename Volume< T >::Position4Di &top, const typename Volume< T >::Position4Di &bottom=typename Volume< T >::Position4Di(-1, -1, -1, -1))
Set border width.
Definition: volumeutil.h:960
Volume< bool > valuesIn(const Volume< T > &volume, const U &set)
Find values contained in a set.
Definition: volumeutil.h:849
Volume< OUTP > & applyTowards(const Volume< T > &vol, Volume< OUTP > &dst, UnaryFunction func)
Apply a function to all the elements of a volume (already allocated output version) ...
Definition: volumeutil.h:428
T * get() const
Volume< typename UnaryFunction::result_type > apply(const Volume< T > &vol, UnaryFunction func)
Used by the actual Volume and VolumeRef operators It allows to keep the loops in one place and to spe...
Definition: volumeutil.h:353
int getSizeY() const
Definition: volumeproxy.h:97
std::complex< double > cdouble
const PropertySet & header() const
static T accumulate(BinaryFunction f, const VolumeRef< T > &o2, T initial)
Apply a binary function to each voxel of the volume, with a "current" value as second argument...
Definition: volumeutil.h:1272
int getSizeT() const
Definition: volumeproxy.h:117
changeIf(const T &value)
Definition: volumeutil.h:898
Volume< T > invertMinMax(const Volume< T > &volume)
Invert a volume between its min and max values.
Definition: volumeutil.h:940
OUTP accumulate(const Volume< T > &vol, BinaryFunction func, OUTP initial)
Accumulation over a volume.
Definition: volumeutil.h:453