cartodata  4.5.0
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  T sum( const Volume<T> & vol );
214  template <typename OUTP, typename T>
215  OUTP sum( const Volume<T> & vol );
216  template <typename T>
217  T 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  // DEFINITIONS
339  //
340  //==========================================================================
341 
342  namespace volumeutil {
343 
344  //========================================================================
345  // Generic operators
346  //========================================================================
347 
348  //--- Volume [op] other --------------------------------------------------
349 
350  template <typename T, typename UnaryFunction>
351  Volume<typename UnaryFunction::result_type>
352  apply( const Volume<T> & vol, UnaryFunction func )
353  {
354  typedef typename UnaryFunction::result_type OUTP;
355  Volume<OUTP> output = deepcopy<OUTP,T>(vol);
356  applyTowards( vol, output, func );
357  return output;
358  }
359 
360  template <typename T, typename U, typename BinaryFunction>
362  apply( const Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func )
363  {
364  typedef typename BinaryFunction::result_type OUTP;
365  Volume<OUTP> output = deepcopy<OUTP,T>(vol1);
366  applyTowards( vol1, vol2, output, func );
367  return output;
368  }
369 
370  //--- VolumeRef [op]= other ----------------------------------------------
371 
372  template <typename T, typename UnaryFunction>
374  apply( const rc_ptr<Volume<T> > & vol, UnaryFunction func )
375  {
376  typedef typename UnaryFunction::result_type OUTP;
377  rc_ptr<Volume<OUTP> > output = deepcopy<OUTP,T>(vol);
378  applyTowards( *vol, *output, func );
379  return output;
380  }
381 
382  template <typename T, typename U, typename BinaryFunction>
384  apply( const rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func )
385  {
386  typedef typename BinaryFunction::result_type OUTP;
387  rc_ptr<Volume<OUTP> > output = deepcopy<OUTP,T>(vol1);
388  applyTowards( *vol1, vol2, *output, func );
389  return output;
390  }
391 
392  //--- Volume [op]= other -------------------------------------------------
393 
394  template <typename T, typename UnaryFunction>
395  Volume<T> & selfApply( Volume<T> & vol, UnaryFunction func )
396  {
397  applyTowards( vol, vol, func );
398  return vol;
399  }
400 
401  template <typename T, typename U, typename BinaryFunction>
402  Volume<T> & selfApply( Volume<T> & vol1, const Volume<U> & vol2, BinaryFunction func )
403  {
404  applyTowards( vol1, vol2, vol1, func );
405  return vol1;
406  }
407 
408  //--- VolumeRef [op]= other ----------------------------------------------
409 
410  template <typename T, typename UnaryFunction>
411  rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol, UnaryFunction func )
412  {
413  selfApply( *vol, func );
414  return vol;
415  }
416 
417  template <typename T, typename U, typename BinaryFunction>
418  rc_ptr<Volume<T> > & selfApply( rc_ptr<Volume<T> > & vol1, const Volume<U> & vol2, BinaryFunction func )
419  {
420  selfApply( *vol1, vol2, func );
421  return vol1;
422  }
423 
424  //--- Volume [op] other -> Output ---------------------------------------
425  template <typename T, typename OUTP, typename UnaryFunction>
426  Volume<OUTP> &
427  applyTowards( const Volume<T> & vol, Volume<OUTP> & dst, UnaryFunction func )
428  {
429  for( long t = 0; t < vol.getSizeT(); ++t )
430  for( long z = 0; z < vol.getSizeZ(); ++z )
431  for( long y = 0; y < vol.getSizeY(); ++y )
432  for( long x = 0; x < vol.getSizeX(); ++x )
433  dst( x, y, z, t ) = func( vol( x, y, z, t ) );
434  return dst;
435  }
436 
437  template <typename T, typename U, typename OUTP, typename BinaryFunction>
438  Volume<OUTP> &
439  applyTowards( const Volume<T> & vol1, const Volume<U> & vol2, Volume<OUTP> & dst, BinaryFunction func )
440  {
441  for( long t = 0; t < vol1.getSizeT() && t < vol2.getSizeT(); ++t )
442  for( long z = 0; z < vol1.getSizeZ() && z < vol2.getSizeZ(); ++z )
443  for( long y = 0; y < vol1.getSizeY() && y < vol2.getSizeY(); ++y )
444  for( long x = 0; x < vol1.getSizeX() && x < vol2.getSizeX(); ++x )
445  dst( x, y, z, t ) = func( vol1( x, y, z, t ), vol2( x, y, z, t ) );
446  return dst;
447  }
448 
449  //--- Volume: accumulate -------------------------------------------------
450 
451  template <typename OUTP, typename T, typename BinaryFunction>
452  OUTP accumulate( const Volume<T> & vol, BinaryFunction func, OUTP initial )
453  {
454  for( long t = 0; t < vol.getSizeT(); ++t )
455  for( long z = 0; z < vol.getSizeZ(); ++z )
456  for( long y = 0; y < vol.getSizeY(); ++y )
457  for( long x = 0; x < vol.getSizeX(); ++x )
458  initial = func( initial, vol( x, y, z, t ) );
459  return initial;
460  }
461 
462  //--- VolumeRef: accumulate ----------------------------------------------
463 
464  template <typename OUTP, typename T, typename BinaryFunction>
465  OUTP accumulate( const rc_ptr<Volume<T> > & vol, BinaryFunction func, OUTP initial )
466  {
467  return accumulate<OUTP, T, BinaryFunction>( *vol, func, initial );
468  }
469 
470  } // namespace volumeutil
471 
472  //==========================================================================
473  // Copy functions
474  //==========================================================================
475 
476  //--- transfer -------------------------------------------------------------
477 
478  template <typename T>
479  void transfer( const Volume<T> & src, Volume<T> & dst )
480  {
481  transfer<T,T>( src, dst );
482  }
483 
484  template <typename T>
485  void transfer( const rc_ptr<Volume<T> > & src, rc_ptr<Volume<T> > & dst )
486  {
487  transfer<T,T>( src, dst );
488  }
489 
490  template <typename OUTP, typename INP>
491  void transfer( const Volume<INP> & src, Volume<OUTP> & dst )
492  {
493  volumeutil::applyTowards( src, dst, volumeutil::identity<INP>() );
494  }
495 
496  template <typename OUTP, typename INP>
497  void transfer( const rc_ptr<Volume<INP> > & src, rc_ptr<Volume<OUTP> > & dst )
498  {
499  transfer( *src, *dst );
500  }
501 
502  //--- deepcopy -------------------------------------------------------------
503 
504  template <typename T>
505  Volume<T> deepcopy( const Volume<T> & src )
506  {
507  return deepcopy<T,T>( src );
508  }
509 
510  template <typename T>
511  rc_ptr<Volume<T> > deepcopy( const rc_ptr<Volume<T> > & src )
512  {
513  return deepcopy<T,T>( src );
514  }
515 
516  template <typename OUTP, typename INP>
517  Volume<OUTP> deepcopy( const Volume<INP> & src )
518  {
519  Volume<OUTP> dst( src.getSizeX(), src.getSizeY(),
520  src.getSizeZ(), src.getSizeT(),
521  src.allocatorContext(),
522  src.allocatorContext().isAllocated() );
523  dst.copyHeaderFrom( src.header() );
524  if( src.allocatorContext().isAllocated() )
525  transfer( src, dst );
526 
527  if( src.refVolume() )
528  {
529  rc_ptr<Volume<INP> > srcparent = src.refVolume();
530  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
531  srcparent->getSizeX(), srcparent->getSizeY(),
532  srcparent->getSizeZ(), srcparent->getSizeT(),
533  srcparent->allocatorContext(),
534  srcparent->allocatorContext().isAllocated() ) );
535  if( srcparent->allocatorContext().isAllocated() )
536  transfer( srcparent, dstparent );
537  dst.setRefVolume( dstparent );
538  dst.setPosInRefVolume( src.posInRefVolume() );
539  }
540 
541  rc_ptr<Volume<INP> > srcchild = src.refVolume();
542  rc_ptr<Volume<OUTP> > dstchild = dst.refVolume();
543 
544  while( srcchild->refVolume().get() )
545  {
546  rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
547  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
548  srcparent->getSizeX(), srcparent->getSizeY(),
549  srcparent->getSizeZ(), srcparent->getSizeT(),
550  srcparent->allocatorContext(),
551  srcparent->allocatorContext().isAllocated() ) );
552  dstparent->copyHeaderFrom( srcparent->header() );
553  if( srcparent->allocatorContext().isAllocated() )
554  transfer( srcparent, dstparent );
555  dstchild->setRefVolume( dstparent );
556  dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
557  srcchild = srcparent;
558  dstchild = dstparent;
559  }
560 
561  return dst;
562  }
563 
564  template <typename OUTP, typename INP>
565  rc_ptr<Volume<OUTP> > deepcopy( const rc_ptr<Volume<INP> > & src )
566  {
567  rc_ptr<Volume<OUTP> > dst( new Volume<OUTP>(
568  src->getSizeX(), src->getSizeY(),
569  src->getSizeZ(), src->getSizeT(),
570  src->allocatorContext(),
571  src->allocatorContext().isAllocated() ) );
572  dst->copyHeaderFrom( src->header() );
573  if( src->allocatorContext().isAllocated() )
574  transfer( src, dst );
575 
576  rc_ptr<Volume<INP> > srcchild = src;
577  rc_ptr<Volume<OUTP> > dstchild = dst;
578 
579  while( srcchild->refVolume().get() )
580  {
581  rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
582  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
583  srcparent->getSizeX(), srcparent->getSizeY(),
584  srcparent->getSizeZ(), srcparent->getSizeT(),
585  srcparent->allocatorContext(),
586  srcparent->allocatorContext().isAllocated() ) );
587  dstparent->copyHeaderFrom( srcparent->header() );
588  if( srcparent->allocatorContext().isAllocated() )
589  transfer( srcparent, dstparent );
590  dstchild->setRefVolume( dstparent );
591  dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
592  srcchild = srcparent;
593  dstchild = dstparent;
594  }
595 
596  return dst;
597  }
598 
599 
600  //--- copy -----------------------------------------------------------------
601 
602  template <typename T>
603  Volume<T> copy( const Volume<T> & src )
604  {
605  return copy<T,T>( src );
606  }
607 
608  template <typename T>
609  rc_ptr<Volume<T> > copy( const rc_ptr<Volume<T> > & src )
610  {
611  return copy<T,T>( src );
612  }
613 
614  template <typename OUTP, typename INP>
615  Volume<OUTP> copy( const Volume<INP> & src )
616  {
617  Volume<OUTP> dst( src.getSizeX(), src.getSizeY(),
618  src.getSizeZ(), src.getSizeT() );
619  dst.copyHeaderFrom( src.header() );
620  transfer( src, dst );
621  return dst;
622  }
623 
624  template <typename OUTP, typename INP>
625  rc_ptr<Volume<OUTP> > copy( const rc_ptr<Volume<INP> > & src )
626  {
627  rc_ptr<Volume<OUTP> > dst( new Volume<OUTP>(
628  src->getSizeX(), src->getSizeY(),
629  src->getSizeZ(), src->getSizeT() ) );
630  dst->copyHeaderFrom( src->header() );
631  transfer( src, dst );
632  return dst;
633  }
634 
635 
636  //--- copyStructure --------------------------------------------------------
637 
638  template <typename T>
639  Volume<T> copyStructure( const Volume<T> & src )
640  {
641  return copyStructure<T,T>( src );
642  }
643 
644  template <typename T>
645  rc_ptr<Volume<T> > copyStructure( const rc_ptr<Volume<T> > & src )
646  {
647  return copyStructure<T,T>( src );
648  }
649 
650  template <typename OUTP, typename INP>
651  Volume<OUTP> copyStructure( const Volume<INP> & src )
652  {
653  Volume<OUTP> dst( src.getSizeX(), src.getSizeY(),
654  src.getSizeZ(), src.getSizeT(),
655  src.allocatorContext(),
656  src.allocatorContext().isAllocated() );
657  dst.copyHeaderFrom( src.header() );
658  // if( src.allocatorContext().isAllocated() )
659  // dst.fill(0);
660 
661  if( src.refVolume() )
662  {
663  rc_ptr<Volume<INP> > srcparent = src.refVolume();
664  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
665  srcparent->getSizeX(), srcparent->getSizeY(),
666  srcparent->getSizeZ(), srcparent->getSizeT(),
667  srcparent->allocatorContext(),
668  srcparent->allocatorContext().isAllocated() ) );
669  // if( srcparent->allocatorContext().isAllocated() )
670  // dstparent->fill(0);
671  dst.setRefVolume( dstparent );
672  dst.setPosInRefVolume( src.posInRefVolume() );
673  }
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  return dst;
696  }
697 
698  template <typename OUTP, typename INP>
699  rc_ptr<Volume<OUTP> > copyStructure( const rc_ptr<Volume<INP> > & src )
700  {
701  rc_ptr<Volume<OUTP> > dst( new Volume<OUTP>(
702  src->getSizeX(), src->getSizeY(),
703  src->getSizeZ(), src->getSizeT(),
704  src->allocatorContext(),
705  src->allocatorContext().isAllocated() ) );
706  dst->copyHeaderFrom( src->header() );
707  // if( src->allocatorContext().isAllocated() )
708  // dst->fill(0);
709 
710  rc_ptr<Volume<INP> > srcchild = src;
711  rc_ptr<Volume<OUTP> > dstchild = dst;
712 
713  while( srcchild->refVolume().get() )
714  {
715  rc_ptr<Volume<INP> > srcparent = srcchild->refVolume();
716  rc_ptr<Volume<OUTP> > dstparent( new Volume<OUTP>(
717  srcparent->getSizeX(), srcparent->getSizeY(),
718  srcparent->getSizeZ(), srcparent->getSizeT(),
719  srcparent->allocatorContext(),
720  srcparent->allocatorContext().isAllocated() ) );
721  dstparent->copyHeaderFrom( srcparent->header() );
722  // if( srcparent->allocatorContext().isAllocated() )
723  // dstparent->fill(0);
724  dstchild->setRefVolume( dstparent );
725  dstchild->setPosInRefVolume( srcchild->posInRefVolume() );
726  srcchild = srcparent;
727  dstchild = dstparent;
728  }
729 
730  return dst;
731  }
732 
733 
734  //==========================================================================
735  // Min/Max/Sum/Any/All
736  //==========================================================================
737 
738  template <typename T>
739  T min( const Volume<T> & vol )
740  {
741  if( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
742  vol.getSizeZ() == 0 && vol.getSizeT() == 0 )
743  throw std::runtime_error("Cannot compute min of an empty volume");
744  return accumulate( vol, volumeutil::select_min<T>(), vol.at(0, 0, 0, 0) );
745  }
746 
747  template <typename T>
748  T min( const rc_ptr<Volume<T> > & vol )
749  {
750  if( !vol.get() || ( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
751  vol.getSizeZ() == 0 && vol.getSizeT() == 0 ) )
752  throw std::runtime_error("Cannot compute min of an empty volume");
753  return accumulate( vol, volumeutil::select_min<T>(), vol->at(0, 0, 0, 0) );
754  }
755 
756  template <typename T>
757  T max( const Volume<T> & vol )
758  {
759  if( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
760  vol.getSizeZ() == 0 && vol.getSizeT() == 0 )
761  throw std::runtime_error("Cannot compute max of an empty volume");
762  return accumulate( vol, volumeutil::select_max<T>(), vol.at(0, 0, 0, 0) );
763  }
764 
765  template <typename T>
766  T max( const rc_ptr<Volume<T> > & vol )
767  {
768  if( !vol.get() || ( vol.getSizeX() == 0 && vol.getSizeY() == 0 &&
769  vol.getSizeZ() == 0 && vol.getSizeT() == 0 ) )
770  throw std::runtime_error("Cannot compute max of an empty volume");
771  return accumulate( vol, volumeutil::select_max<T>(), vol->at(0, 0, 0, 0) );
772  }
773 
774  template <typename T>
775  T sum( const Volume<T> & vol )
776  {
777  return sum<T,T>( vol );
778  }
779 
780 
781  template <typename OUTP, typename T>
782  OUTP sum( const Volume<T> & vol )
783  {
784  return accumulate( vol, volumeutil::plus<OUTP,T>(), static_cast<OUTP>(0) );
785  }
786 
787  template <typename T>
788  T sum( const rc_ptr<Volume<T> > & vol )
789  {
790  return sum<T,T>( vol );
791  }
792 
793  template <typename OUTP, typename T>
794  OUTP sum( const rc_ptr<Volume<T> > & vol )
795  {
796  if( !vol.get() )
797  return static_cast<OUTP>(0);
798  return accumulate( vol, volumeutil::plus<OUTP,T>(), static_cast<OUTP>(0) );
799  }
800 
801  template <typename T>
802  bool all( const Volume<T> & vol )
803  {
804  return volumeutil::accumulate( vol, volumeutil::logical_and<bool,T>(), true );
805  }
806 
807  template <typename T>
808  bool all( const rc_ptr<Volume<T> > & vol )
809  {
810  return volumeutil::accumulate( *vol, volumeutil::logical_and<bool,T>(), true );
811  }
812 
813  template <typename T>
814  bool any( const Volume<T> & vol )
815  {
816  return volumeutil::accumulate( vol, volumeutil::logical_or<bool,T>(), false );
817  }
818 
819  template <typename T>
820  bool any( const rc_ptr<Volume<T> > & vol )
821  {
822  return volumeutil::accumulate( *vol, volumeutil::logical_or<bool,T>(), false );
823  }
824 
825  //==========================================================================
826  // Special operators
827  //==========================================================================
828 
829  namespace internal {
830  template <typename T, typename U>
831  struct inSet: public std::binary_function<T, U, bool>
832  {
833  bool operator() ( const T & x, const U & y )
834  {
835  for( typename U::const_iterator k = y.begin(); k != y.end(); ++k )
836  if( x == *k )
837  return true;
838  return false;
839  }
840  };
841  } // namespace internal
842 
843  template <typename T, typename U>
844  Volume<bool> valuesIn( const Volume<T> & volume, const U & set )
845  {
846  Volume<bool> output = copyStructure<bool, T>( volume );
847  volumeutil::applyTowards( volume, output, std::bind2nd( internal::inSet<T,U>(), set ) );
848  return output;
849  }
850 
851  template <typename T, typename U>
852  rc_ptr<Volume<bool> > valuesIn( const rc_ptr<Volume<T> > & volume, const U & set )
853  {
854  rc_ptr<Volume<bool> > output = copyStructure<bool, T>( volume );
855  volumeutil::applyTowards( *volume, *output, std::bind2nd( internal::inSet<T,U>(), set ) );
856  return output;
857  }
858 
859  namespace internal {
860  template <typename T, typename U>
861  struct notInSet: public std::binary_function<T, U, bool>
862  {
863  bool operator() ( const T & x, const U & y )
864  {
865  for( typename U::const_iterator k = y.begin(); k != y.end(); ++k )
866  if( x == *k )
867  return false;
868  return true;
869  }
870  };
871  } // namespace internal
872 
873  template <typename T, typename U>
874  Volume<bool> valuesNotIn( const Volume<T> & volume, const U & set )
875  {
876  Volume<bool> output = copyStructure<bool, T>( volume );
877  volumeutil::applyTowards( volume, output, std::bind2nd( internal::notInSet<T,U>(), set ) );
878  return output;
879  }
880 
881  template <typename T, typename U>
882  rc_ptr<Volume<bool> > valuesNotIn( const rc_ptr<Volume<T> > & volume, const U & set )
883  {
884  rc_ptr<Volume<bool> > output = copyStructure<bool, T>( volume );
885  volumeutil::applyTowards( *volume, *output, std::bind2nd( internal::notInSet<T,U>(), set ) );
886  return output;
887  }
888 
889  namespace internal {
890  template <typename T, typename U>
891  struct changeIf: public std::binary_function<T, U, T>
892  {
893  changeIf( const T & value ): _value(value) {}
894  bool operator() ( const T & x, const U & y )
895  {
896  return y ? _value : x;
897  }
898  private:
899  T _value;
900  };
901  } // namespace internal
902 
903  template <typename T, typename U>
904  void conditionalSet( Volume<T> & volume, const Volume<U> & condition, const T & value )
905  {
906  volumeutil::selfApply( volume, condition, internal::changeIf<T,U>(value) );
907  }
908 
909  template <typename T, typename U>
910  void conditionalSet( rc_ptr<Volume<T> > & volume, const rc_ptr<Volume<U> > & condition, const T & value )
911  {
912  volumeutil::selfApply( volume, *condition, internal::changeIf<T,U>(value) );
913  }
914 
915  namespace internal {
916  template <typename T>
917  struct invMinMax: public std::unary_function<T, T>
918  {
919  invMinMax( const T & min, const T & max ):
920  _min(min),
921  _max(max)
922  {}
923 
924  T operator() ( const T & x )
925  {
926  return max - x + min;
927  }
928  private:
929  T _min;
930  T _max;
931  };
932  } // namespace internal
933 
934  template <typename T>
935  Volume<T> invertMinMax( const Volume<T> & volume )
936  {
937  T min = min( volume );
938  T max = max( volume );
939  volumeutil::apply( volume, internal::invMinMax<T>(min, max) );
940  }
941 
942  template <typename T>
943  rc_ptr<Volume<T> > invertMinMax( const rc_ptr<Volume<T> > & volume )
944  {
945  T min = min( volume );
946  T max = max( volume );
947  volumeutil::apply( volume, internal::invMinMax<T>(min, max) );
948  }
949 
950  //==========================================================================
951  // Borders
952  //==========================================================================
953 
954  template <typename T>
955  void setBorders( Volume<T> & volume,
956  const typename Volume<T>::Position4Di & top,
957  const typename Volume<T>::Position4Di & bottom )
958  {
959  const typename Volume<T>::Position4Di & bot =
960  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
961  top : bottom );
962  std::vector<int> b = volume.getBorders();
963  if( b[0] != top[0] || b[1] != bot[0] ||
964  b[2] != top[1] || b[3] != bot[1] ||
965  b[4] != top[2] || b[5] != bot[2] ||
966  b[6] != top[3] || b[7] != bot[3] )
967  {
968  rc_ptr<Volume<T> > parent( new Volume<T>(
969  volume.getSizeX() + top[0] + bot[0],
970  volume.getSizeY() + top[1] + bot[1],
971  volume.getSizeZ() + top[2] + bot[2],
972  volume.getSizeT() + top[3] + bot[3] ) );
973  parent->copyHeaderFrom( volume.header() );
974  typename Volume<T>::Position4Di size( volume.getSizeX(),
975  volume.getSizeY(),
976  volume.getSizeZ(),
977  volume.getSizeT() );
978  Volume<T> view( parent, top, size );
979  transfer( volume, view );
980  volume.reallocate( volume.getSizeX(), volume.getSizeY(),
981  volume.getSizeZ(), volume.getSizeT(),
982  true, volume.allocatorContext(), false );
983  volume.setRefVolume( parent );
984  volume.setPosInRefVolume( top );
985  }
986  }
987 
988  template <typename T>
989  void setBorders( rc_ptr<Volume<T> > & volume,
990  const typename Volume<T>::Position4Di & top,
991  const typename Volume<T>::Position4Di & bottom )
992  {
993  const typename Volume<T>::Position4Di & bot =
994  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
995  top : bottom );
996  std::vector<int> b = volume->getBorders();
997  if( b[0] != top[0] || b[1] != bot[0] ||
998  b[2] != top[1] || b[3] != bot[1] ||
999  b[4] != top[2] || b[5] != bot[2] ||
1000  b[6] != top[3] || b[7] != bot[3] )
1001  {
1002  rc_ptr<Volume<T> > parent( new Volume<T>(
1003  volume->getSizeX() + top[0] + bot[0],
1004  volume->getSizeY() + top[1] + bot[1],
1005  volume->getSizeZ() + top[2] + bot[2],
1006  volume->getSizeT() + top[3] + bot[3] ) );
1007  parent->copyHeaderFrom( volume->header() );
1008  typename Volume<T>::Position4Di size( volume->getSizeX(),
1009  volume->getSizeY(),
1010  volume->getSizeZ(),
1011  volume->getSizeT() );
1012  rc_ptr<Volume<T> > view( new Volume<T>( parent, top, size ) );
1013  transfer( volume, view );
1014  volume->reallocate( volume->getSizeX(), volume->getSizeY(),
1015  volume->getSizeZ(), volume->getSizeT(),
1016  true, volume->allocatorContext(), false );
1017  volume->setRefVolume( parent );
1018  volume->setPosInRefVolume( top );
1019  }
1020  }
1021 
1022  template <typename T>
1023  void setMinBorders( Volume<T> & volume,
1024  const typename Volume<T>::Position4Di & top,
1025  const typename Volume<T>::Position4Di & bottom )
1026  {
1027  const typename Volume<T>::Position4Di & bot =
1028  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1029  top : bottom );
1030  std::vector<int> b = volume.getBorders();
1031  if( b[0] < top[0] || b[1] < bot[0] ||
1032  b[2] < top[1] || b[3] < bot[1] ||
1033  b[4] < top[2] || b[5] < bot[2] ||
1034  b[6] < top[3] || b[7] < bot[3] )
1035  {
1036  rc_ptr<Volume<T> > parent( new Volume<T>(
1037  volume.getSizeX() + top[0] + bot[0],
1038  volume.getSizeY() + top[1] + bot[1],
1039  volume.getSizeZ() + top[2] + bot[2],
1040  volume.getSizeT() + top[3] + bot[3] ) );
1041  parent->copyHeaderFrom( volume.header() );
1042  typename Volume<T>::Position4Di size( volume.getSizeX(),
1043  volume.getSizeY(),
1044  volume.getSizeZ(),
1045  volume.getSizeT() );
1046  Volume<T> view( parent, top, size );
1047  transfer( volume, view );
1048  volume.reallocate( volume.getSizeX(), volume.getSizeY(),
1049  volume.getSizeZ(), volume.getSizeT(),
1050  true, volume.allocatorContext(), false );
1051  volume.setRefVolume( parent );
1052  volume.setPosInRefVolume( top );
1053  }
1054  }
1055 
1056  template <typename T>
1057  void setMinBorders( rc_ptr<Volume<T> > & volume,
1058  const typename Volume<T>::Position4Di & top,
1059  const typename Volume<T>::Position4Di & bottom )
1060  {
1061  const typename Volume<T>::Position4Di & bot =
1062  ( bottom == typename Volume<T>::Position4Di(-1, -1, -1, -1) ?
1063  top : bottom );
1064  std::vector<int> b = volume->getBorders();
1065  if( b[0] < top[0] || b[1] < bot[0] ||
1066  b[2] < top[1] || b[3] < bot[1] ||
1067  b[4] < top[2] || b[5] < bot[2] ||
1068  b[6] < top[3] || b[7] < bot[3] )
1069  {
1070  rc_ptr<Volume<T> > parent( new Volume<T>(
1071  volume->getSizeX() + top[0] + bot[0],
1072  volume->getSizeY() + top[1] + bot[1],
1073  volume->getSizeZ() + top[2] + bot[2],
1074  volume->getSizeT() + top[3] + bot[3] ) );
1075  parent->copyHeaderFrom( volume->header() );
1076  typename Volume<T>::Position4Di size( volume->getSizeX(),
1077  volume->getSizeY(),
1078  volume->getSizeZ(),
1079  volume->getSizeT() );
1080  rc_ptr<Volume<T> > view( new Volume<T>( parent, top, size ) );
1081  transfer( volume, view );
1082  volume->reallocate( volume->getSizeX(), volume->getSizeY(),
1083  volume->getSizeZ(), volume->getSizeT(),
1084  true, volume->allocatorContext(), false );
1085  volume->setRefVolume( parent );
1086  volume->setPosInRefVolume( top );
1087  }
1088  }
1089 
1090  //==========================================================================
1091  //
1092  // OLD CLASSES / METHODS
1093  //
1094  //==========================================================================
1095  template <typename T> class VolumeRef;
1096 
1097 
1103  template <typename T, class BinaryFunction>
1105  {
1106  public:
1107  inline UnaryFromConstantBinaryFunctor( const T & x, BinaryFunction func )
1108  : value( x ), f( func ) {}
1109  inline T operator () ( const T & y ) const
1110  { return f( y, value ); }
1112  BinaryFunction f;
1113  };
1114 
1115 
1120  template <typename T, class BinaryFunction>
1122  {
1123  public:
1124  inline UnaryFromConstantBinaryFunctor2( const T & x, BinaryFunction func )
1125  : value( x ), f( func ) {}
1126  inline T operator () ( const T & y ) const
1127  { return f( value, y ); }
1129  BinaryFunction f;
1130  };
1135  template <typename T, typename U>
1136  class Scaler
1137  {
1138  public:
1139  inline Scaler( U x ) : scale( x ) {}
1140  inline T operator () ( const T & x ) const
1141  { return (T) ( x * scale ); }
1143  };
1144 
1145  template<> inline cfloat
1147  {
1148  return x * (float) scale;
1149  }
1150 
1151  template<> inline cfloat
1153  {
1154  return x * (float) scale;
1155  }
1156 
1157  template<> inline cdouble
1159  {
1160  return x * (double) scale;
1161  }
1162 
1163  template<> inline cdouble
1165  {
1166  return x * (double) scale;
1167  }
1168 
1173  template <typename T, typename U>
1174  class Divider
1175  {
1176  public:
1177  inline Divider( U x ) : divisor( x ) {}
1178  inline T operator () ( const T & x ) const
1179  { return (T) ( x / divisor ); }
1181  };
1182 
1183  template<> inline cfloat
1185  {
1186  return x * (float) ( 1. / divisor );
1187  }
1188 
1189  template<> inline cfloat
1191  {
1192  return x * (float) ( 1. / (double) divisor );
1193  }
1194 
1195  template<> inline cdouble
1197  {
1198  return x * ( 1. / divisor );
1199  }
1200 
1201  template<> inline cdouble
1203  {
1204  return x * (double) ( 1. / divisor );
1205  }
1206 
1207  template<> inline cdouble
1209  {
1210  return x * (double) ( 1. / divisor );
1211  }
1212 
1213  template <typename T, bool Scalar>
1215  };
1216 
1218  template <typename T>
1219  class VolumeUtilBase<T, true> {
1220  public :
1223  static T min( const Volume<T> & o );
1224 
1227  static T max( const Volume<T> & o );
1228  };
1229 
1231  template <typename T>
1232  class VolumeUtilBase<T, false> {
1233  };
1234 
1236  template <typename T>
1237  class VolumeUtil: public carto::VolumeUtilBase<T, carto::DataTypeTraits<T>::is_scalar>
1238  {
1239  public:
1241  template <class UnaryFunction> static
1242  VolumeRef<T> apply( UnaryFunction f, const VolumeRef<T> & o );
1244  template <class BinaryFunction> static
1245  VolumeRef<T> apply( BinaryFunction f, const VolumeRef<T> & o1,
1246  const VolumeRef<T> & o2 );
1249  template <class UnaryFunction> static
1250  void selfApply( UnaryFunction f, VolumeRef<T> & o );
1253  template <class BinaryFunction> static
1254  void selfApply( BinaryFunction f, VolumeRef<T> & o1,
1255  const VolumeRef<T> & o2 );
1266  template <class BinaryFunction> static
1267  T accumulate( BinaryFunction f, const VolumeRef<T> & o2, T initial )
1268  { return accumulate( f, *o2, initial ); }
1269  template <class BinaryFunction> static
1270  T accumulate( BinaryFunction f, const Volume<T> & o2, T initial );
1271  };
1272 
1273 } // namespace carto
1274 
1275 #endif // CARTODATA_VOLUME_VOLUMEUTIL_H
1276 
OUTP accumulate(const rc_ptr< Volume< T > > &vol, BinaryFunction func, OUTP initial)
Definition: volumeutil.h:465
4D 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:395
static VolumeRef< T > apply(UnaryFunction f, const VolumeRef< T > &o)
applies a unary function to each voxel of a volume
Definition: volumeutil_d.h:72
bool operator()(const T &x, const U &y)
Definition: volumeutil.h:863
int getSizeT() const
Definition: volumeproxy.h:118
bool operator()(const T &x, const U &y)
Definition: volumeutil.h:894
Divider functor.
Definition: volumeutil.h:1174
Convenient handle for a Volume - this is normally the entry point for all volumes handling...
invMinMax(const T &min, const T &max)
Definition: volumeutil.h:919
Scaler functor.
Definition: volumeutil.h:1136
std::complex< float > cfloat
UnaryFromConstantBinaryFunctor2(const T &x, BinaryFunction func)
Definition: volumeutil.h:1124
Volume utilities classes.
Definition: volumeutil.h:1237
T operator()(const T &x) const
Definition: volumeutil.h:1140
UnaryFromConstantBinaryFunctor(const T &x, BinaryFunction func)
Definition: volumeutil.h:1107
int getSizeZ() const
Definition: volumeproxy.h:108
bool operator()(const T &x, const U &y)
Definition: volumeutil.h:833
int getSizeX() const
Definition: volumeproxy.h:88
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:427
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:352
T operator()(const T &x)
Definition: volumeutil.h:924
T operator()(const T &x) const
Definition: volumeutil.h:1178
std::complex< double > cdouble
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:1267
static void selfApply(UnaryFunction f, VolumeRef< T > &o)
same as apply() except that the input volume is used to store the result
Definition: volumeutil_d.h:280
changeIf(const T &value)
Definition: volumeutil.h:893
OUTP accumulate(const Volume< T > &vol, BinaryFunction func, OUTP initial)
Accumulation over a volume.
Definition: volumeutil.h:452
int getSizeY() const
Definition: volumeproxy.h:98