3d/datafield.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef __MIA_3DDATAFIELD_HH
22 #define __MIA_3DDATAFIELD_HH 1
23 
24 #include <cstdio>
25 #include <vector>
26 #include <cmath>
27 #include <cassert>
28 
29 #include <mia/3d/vector.hh>
30 #include <mia/3d/defines3d.hh>
31 #include <mia/3d/iterator.hh>
32 #include <mia/2d/datafield.hh>
33 #include <mia/core/msgstream.hh>
34 #include <mia/core/parameter.hh>
35 #include <mia/core/typedescr.hh>
36 #include <miaconfig.h>
37 
39 
40 
41 #define DECLARE_EXTERN_ITERATORS(TYPE) \
42  extern template class EXPORT_3D range3d_iterator<std::vector<TYPE>::iterator>; \
43  extern template class EXPORT_3D range3d_iterator<std::vector<TYPE>::const_iterator>; \
44  extern template class EXPORT_3D range3d_iterator_with_boundary_flag<std::vector<TYPE>::iterator>; \
45  extern template class EXPORT_3D range3d_iterator_with_boundary_flag<std::vector<TYPE>::const_iterator>; \
46  extern template class EXPORT_3D range2d_iterator<std::vector<TYPE>::iterator>; \
47  extern template class EXPORT_3D range2d_iterator<std::vector<TYPE>::const_iterator>;
48 
49 
50 #ifdef __GNUC__
51 #pragma GCC diagnostic push
52 #ifndef __clang__
53 #pragma GCC diagnostic ignored "-Wattributes"
54 #endif
55 #endif
56 
59 DECLARE_EXTERN_ITERATORS(uint32_t);
62 DECLARE_EXTERN_ITERATORS(uint16_t);
67 DECLARE_EXTERN_ITERATORS(uint64_t);
68 
69 
72 
73 #ifdef __GNUC__
74 #pragma GCC diagnostic pop
75 #endif
76 
81 template <class T>
83 
84  typedef ::std::vector<typename __holder_type_dispatch<T>::type> data_array;
85 
86 public:
87 
88 
91  void make_single_ref() __attribute__((deprecated));
92 
97  bool holds_unique_data()const __attribute__((deprecated)){
98  return true;
99  }
100 
101 
103 
105  typedef typename data_array::iterator iterator;
106  typedef typename data_array::const_iterator const_iterator;
107  typedef typename data_array::const_reference const_reference;
108  typedef typename data_array::reference reference;
109  typedef typename data_array::const_pointer const_pointer;
110  typedef typename data_array::pointer pointer;
111  typedef typename data_array::value_type value_type;
112  typedef typename data_array::size_type size_type;
113  typedef typename data_array::difference_type difference_type;
114  typedef typename atomic_data<value_type>::type atomic_type;
115  typedef range3d_iterator<iterator> range_iterator;
116  typedef range3d_iterator<const_iterator> const_range_iterator;
117 
118  typedef range3d_iterator_with_boundary_flag<iterator> range_iterator_with_boundary_flag;
119  typedef range3d_iterator_with_boundary_flag<const_iterator> const_range_iterator_with_boundary_flag;
120 
121  typedef C3DBounds dimsize_type;
123 
133  class EXPORT_3D Range {
134  friend class T3DDatafield<T>;
135  friend class ConstRange;
136  public:
137 
139 
140  iterator begin();
141 
142  iterator end();
143 
144  private:
145  Range(const C3DBounds& start, const C3DBounds& end, T3DDatafield<T>& field);
146 
147  iterator m_begin;
148  iterator m_end;
149  };
150 
152  public:
153  friend class T3DDatafield<T>;
154 
156 
157  iterator begin() const;
158 
159  iterator end() const;
160 
161  private:
162  ConstRange(const C3DBounds& start, const C3DBounds& end, const T3DDatafield<T>& field);
163 
164  ConstRange(const Range& range);
165 
166  iterator m_begin;
167  iterator m_end;
168  };
169 
170 
171  T3DDatafield();
172 
174  explicit T3DDatafield(const C3DBounds& _Size);
175 
180  T3DDatafield(const C3DBounds& size, const T *data);
181 
182 
187  T3DDatafield(const C3DBounds& size, const data_array& data);
188 
189 
191  T3DDatafield(const T3DDatafield<T>& org);
192 
195 
197  virtual ~T3DDatafield();
198 
203  template <typename Out>
205 
207  template <typename Out>
208  T3DVector<Out> get_gradient(size_t x, size_t y, size_t z) const;
209 
211  template <typename Out>
212  T3DVector<Out> get_gradient(int index) const;
213 
215  value_type get_interpol_val_at(const T3DVector<float >& p) const __attribute__((deprecated));
216 
219  value_type get_block_avrg(const C3DBounds& Start, const C3DBounds& BlockSize) const;
220 
226 
229 
231  const C3DBounds& get_size() const
232  {
233  return m_size;
234  }
235 
237  void clear();
238 
240  size_type size()const
241  {
242  return m_data.size();
243  }
244 
246  void swap(T3DDatafield& other);
247 
249  value_type get_avg();
250 
253  value_type strip_avg();
254 
256  const_reference operator()(size_t x, size_t y, size_t z) const
257  {
258  // Look if we are inside, and give reference, else give the zero
259  if (x < m_size.x && y < m_size.y && z < m_size.z) {
260  return m_data[x+ m_size.x * (y + m_size.y * z)];
261  }
262  return Zero;
263  }
264 
265 
267  const_reference operator()(const C3DBounds& l)const
268  {
269  return (*this)(l.x,l.y,l.z);
270  }
271 
273  reference operator()(size_t x, size_t y, size_t z)
274  {
275  // Look if we are inside, and give reference, else throw exception
276  // since write access is wanted
277  assert(x < m_size.x && y < m_size.y && z < m_size.z);
278  return m_data[x + m_size.x *(y + m_size.y * z)];
279  }
280 
281 
282 
284  reference operator()(const C3DBounds& l)
285  {
286  return (*this)(l.x,l.y,l.z);
287  }
288 
290  void get_data_line_x(int y, int z, std::vector<T>& buffer)const;
291 
293  void get_data_line_y(int x, int z, std::vector<T>& buffer)const;
294 
296  void get_data_line_z(int x, int y, std::vector<T>& buffer)const;
297 
299  void put_data_line_x(int y, int z, const std::vector<T> &buffer);
300 
302  void put_data_line_y(int x, int z, const std::vector<T> &buffer);
303 
305  void put_data_line_z(int x, int y, const std::vector<T> &buffer);
306 
308  template <class TMask>
309  void mask(const TMask& m);
310 
324  void read_xslice_flat(size_t x, std::vector<atomic_type>& buffer) const;
325 
338  void read_yslice_flat(size_t y, std::vector<atomic_type>& buffer) const;
339 
352  void read_zslice_flat(size_t z, std::vector<atomic_type>& buffer) const;
353 
358  void write_zslice_flat(size_t z, const std::vector<atomic_type>& buffer);
359 
360 
365  void write_yslice_flat(size_t y, const std::vector<atomic_type>& buffer);
366 
371  void write_xslice_flat(size_t x, const std::vector<atomic_type>& buffer);
372 
378  T2DDatafield<T> get_data_plane_xy(size_t z)const;
379 
385  T2DDatafield<T> get_data_plane_yz(size_t x)const;
386 
392  T2DDatafield<T> get_data_plane_xz(size_t y)const;
393 
399  void put_data_plane_xy(size_t z, const T2DDatafield<T>& p);
400 
406  void put_data_plane_yz(size_t x, const T2DDatafield<T>& p);
407 
413  void put_data_plane_xz(size_t y, const T2DDatafield<T>& p);
414 
416  const_iterator begin()const
417  {
418  return m_data.begin();
419  }
420 
424  const_iterator begin_at(size_t x, size_t y, size_t z)const
425  {
426  return m_data.begin() + (z * m_size.y + y) * m_size.x + x;
427  }
428 
429 
433  const_iterator end()const
434  {
435  return m_data.end();
436  }
437 
441  iterator begin()
442  {
443  return m_data.begin();
444  }
445 
446  Range get_range(const C3DBounds& start, const C3DBounds& end);
447 
448  ConstRange get_range(const C3DBounds& start, const C3DBounds& end) const;
449 
452  range_iterator begin_range(const C3DBounds& begin, const C3DBounds& end);
453 
455  range_iterator end_range(const C3DBounds& begin, const C3DBounds& end);
456 
457 
460  const_range_iterator begin_range(const C3DBounds& begin, const C3DBounds& end)const;
461 
463  const_range_iterator end_range(const C3DBounds& begin, const C3DBounds& end)const;
464 
465 
467  range_iterator_with_boundary_flag begin_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end);
468 
470  range_iterator_with_boundary_flag end_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end);
471 
472 
474  const_range_iterator_with_boundary_flag begin_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end)const;
475 
477  const_range_iterator_with_boundary_flag end_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end)const;
478 
479 
488  iterator begin_at(size_t x, size_t y, size_t z)
489  {
490  return m_data.begin() + (z * m_size.y + y) * m_size.x + x;
491  }
492 
496  iterator end()
497  {
498  return m_data.end();
499  }
500 
502  const_reference operator[](int i)const
503  {
504  return m_data[i];
505  }
506 
510  reference operator[](int i)
511  {
512  return m_data[i];
513  }
514 
515 
517  size_t get_plane_size_xy()const
518  {
519  return m_xy;
520  };
521 
522 private:
524  C3DBounds m_size;
525 
527  size_t m_xy;
528 
530  data_array m_data;
531 
533  static const value_type Zero;
534 
535  static const size_t m_elements;
536 
537 };
538 
541 
544 
547 
550 
553 
556 
559 
562 
565 
566 
569 
572 
575 
577 
579 DECLARE_TYPE_DESCR(C3DBounds);
580 DECLARE_TYPE_DESCR(C3DFVector);
581 
582 extern template class EXPORT_3D TAttribute<C3DFVector>;
584 
585 // some implementations
586 
587 template <class T>
588 template <typename Out>
589 T3DVector<Out> T3DDatafield<T>::get_gradient(size_t x, size_t y, size_t z) const
590 {
591  const int sizex = m_size.x;
592  // Look if we are inside the used space
593  if (x - 1 < m_size.x - 2 && y - 1 < m_size.y - 2 && z - 1 < m_size.z - 2) {
594 
595  // Lookup all neccessary Values
596  const T *H = &m_data[x + m_size.x * (y + m_size.y * z)];
597 
598  return T3DVector<Out> (Out((H[1] - H[-1]) * 0.5),
599  Out((H[sizex] - H[-sizex]) * 0.5),
600  Out((H[m_xy] - H[-m_xy]) * 0.5));
601  }
602 
603  return T3DVector<Out>();
604 }
605 
606 
607 template <class T>
608 template <typename Out>
610 {
611  const int sizex = m_size.x;
612  // Lookup all neccessary Values
613  const T *H = &m_data[hardcode];
614 
615  return T3DVector<Out> (Out((H[1] - H[-1]) * 0.5),
616  Out((H[sizex] - H[-sizex]) * 0.5),
617  Out((H[m_xy] - H[-m_xy]) * 0.5));
618 }
619 
620 
624 template <>
625 template <typename Out>
627 {
628 
629  // Lookup all neccessary Values
630  return T3DVector<Out> (Out((m_data[hardcode + 1] - m_data[hardcode -1]) * 0.5),
631  Out((m_data[hardcode + m_size.x] - m_data[hardcode -m_size.x]) * 0.5),
632  Out((m_data[hardcode + m_xy] - m_data[hardcode -m_xy]) * 0.5));
633 }
634 
635 template <class T>
636 template <typename Out>
638 {
639  // This will become really funny
640  const int sizex = m_size.x;
641  // Calculate the int coordinates near the POI
642  // and the distances
643  size_t x = size_t (p.x);
644  float dx = p.x - x;
645  float xm = 1 - dx;
646  size_t y = size_t (p.y);
647  float dy = p.y - y;
648  float ym = 1 - dy;
649  size_t z = size_t (p.z);
650  float dz = p.z - z;
651  float zm = 1 - dz;
652 
653  // Look if we are inside the used space
654  if (x-1 < m_size.x-3 && y -1 < m_size.y-3 && z - 1 < m_size.z-3 ) {
655  // Lookup all neccessary Values
656  const T *H000 = &m_data[x + sizex * y + m_xy * z];
657 
658  const T* H_100 = &H000[-m_xy];
659  const T* H_101 = &H_100[1];
660  const T* H_110 = &H_100[sizex];
661  const T* H_111 = &H_110[1];
662 
663  const T* H0_10 = &H000[-sizex];
664  const T* H0_11 = &H0_10[1];
665 
666  const T* H00_1 = &H000[-1];
667  const T* H001 = &H000[ 1];
668  const T* H002 = &H000[ 2];
669 
670 
671  const T* H010 = &H000[sizex];
672  const T* H011 = &H010[ 1];
673  const T* H012 = &H010[ 2];
674  const T* H01_1 = &H010[-1];
675 
676  const T* H020 = &H010[sizex];
677  const T* H021 = &H020[ 1];
678 
679  const T* H100 = &H000[m_xy];
680 
681  const T* H1_10 = &H100[sizex];
682  const T* H1_11 = &H1_10[1];
683 
684  const T* H10_1 = &H100[-1];
685  const T* H101 = &H100[ 1];
686  const T* H102 = &H100[ 2];
687 
688  const T* H110 = &H100[sizex];
689  const T* H111 = &H110[ 1];
690  const T* H112 = &H110[ 2];
691  const T* H11_1 = &H110[-1];
692 
693  const T* H120 = &H110[sizex];
694  const T* H121 = &H120[ 1];
695 
696  const T* H200 = &H100[m_xy];
697  const T* H201 = &H200[1];
698  const T* H210 = &H200[sizex];
699  const T* H211 = &H210[1];
700 
701  // use trilinear interpolation to calc the gradient
702  return T3DVector<Out> (
703  Out((zm * (ym * (dx * (*H002 - *H000) + xm * (*H001 - *H00_1))+
704  dy * (dx * (*H012 - *H010) + xm * (*H011 - *H01_1)))+
705  dz * (ym * (dx * (*H102 - *H100) + xm * (*H101 - *H10_1))+
706  dy * (dx * (*H112 - *H110) + xm * (*H111 - *H11_1)))) * 0.5),
707 
708  Out((zm * (ym * (xm * (*H010 - *H0_10) + dx * (*H011 - *H0_11))+
709  dy * (xm * (*H020 - *H000) + dx * (*H021 - *H001)))+
710  dz * (ym * (xm * (*H110 - *H1_10) + dx * (*H111 - *H1_11))+
711  dy * (xm * (*H120 - *H100) + dx * (*H121 - *H101)))) * 0.5),
712  Out((zm * (ym * (xm * (*H100 - *H_100) + dx * (*H101 - *H_101))+
713  dy * (xm * (*H110 - *H_110) + dx * (*H111 - *H_111)))+
714  dz * (ym * (xm * (*H200 - *H000) + dx * (*H201 - *H001))+
715  dy * (xm * (*H210 - *H010) + dx * (*H211 - *H011)))) * 0.5));
716  }
717  return T3DVector<Out>();
718 
719 }
720 
721 #ifdef __GNUC__
722 #pragma GCC diagnostic push
723 #ifndef __clang__
724 #pragma GCC diagnostic ignored "-Wattributes"
725 #endif
726 #endif
727 
728 #define DECLARE_EXTERN(TYPE) \
729  extern template class EXPORT_3D T3DDatafield<TYPE>;
730 
731 
732 DECLARE_EXTERN(double);
733 DECLARE_EXTERN(float);
734 DECLARE_EXTERN(uint8_t);
735 DECLARE_EXTERN(uint16_t);
736 DECLARE_EXTERN(uint32_t);
737 DECLARE_EXTERN(uint64_t);
738 DECLARE_EXTERN(int8_t);
739 DECLARE_EXTERN(int16_t);
740 DECLARE_EXTERN(int32_t);
741 DECLARE_EXTERN(int64_t);
742 
745 
746 extern template class EXPORT_3D CTParameter<C3DBounds>;
747 extern template class EXPORT_3D CTParameter<C3DFVector>;
748 extern template class EXPORT_3D TTranslator<C3DFVector>;
749 extern template class EXPORT_3D TAttribute<C3DFVector>;
750 
751 
752 #undef DECLARE_EXTERN
753 
754 #ifdef __GNUC__
755 #pragma GCC diagnostic pop
756 #endif
757 
759 
760 #endif
T3DDatafield< T >::range_iterator iterator
void put_data_plane_xy(size_t z, const T2DDatafield< T > &p)
range_iterator begin_range(const C3DBounds &begin, const C3DBounds &end)
const_reference operator()(const C3DBounds &l) const
T3DDatafield< int64_t > C3DLDatafield
a data field of 32 bit signed int values
a 3D iterator that knows its position in the 3D grid ans supports iterating over sub-ranges ...
Definition: 3d/iterator.hh:189
void swap(T3DDatafield &other)
swap the data ofthis 3DDatafield with another one
Generic string vs. attribute translator singleton.
Definition: attributes.hh:509
const_iterator end() const
void write_yslice_flat(size_t y, const std::vector< atomic_type > &buffer)
void put_data_line_y(int x, int z, const std::vector< T > &buffer)
range_iterator_with_boundary_flag begin_range_with_boundary_flags(const C3DBounds &begin, const C3DBounds &end)
T z
vector element
Definition: 3d/vector.hh:55
a 3D iterator that knows its position in the 3D grid, has a flag indicating whether it is on a bounda...
Definition: 3d/iterator.hh:43
A templated class of a 3D data field.
Definition: 3d/datafield.hh:82
iterator begin_at(size_t x, size_t y, size_t z)
void read_zslice_flat(size_t z, std::vector< atomic_type > &buffer) const
T3DDatafield< uint64_t > C3DULDatafield
a data field of 32 bit unsigned int values
T2DDatafield< T > get_data_plane_xz(size_t y) const
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
T3DDatafield< uint16_t > C3DUSDatafield
a data field of 32 bit unsigned int values
T3DDatafield< bool > C3DBitDatafield
a data field of float values
const_iterator begin() const
#define EXPORT_3D
Definition: defines3d.hh:44
value_type get_block_avrg(const C3DBounds &Start, const C3DBounds &BlockSize) const
void get_data_line_x(int y, int z, std::vector< T > &buffer) const
reference operator[](int i)
CTParameter< C3DBounds > C3DBoundsParameter
3D size parameter type
void get_data_line_y(int x, int z, std::vector< T > &buffer) const
value_type strip_avg()
TTranslator< C3DFVector > C3DFVectorTranslator
Range get_range(const C3DBounds &start, const C3DBounds &end)
const_iterator begin_at(size_t x, size_t y, size_t z) const
Generic type of a complex paramter.
Definition: parameter.hh:169
EXPORT_2D C2DFVectorfield get_gradient(const C2DImage &image)
T3DDatafield< int8_t > C3DSBDatafield
a data field of 8 bit int values
T y
vector element
Definition: 3d/vector.hh:53
void write_xslice_flat(size_t x, const std::vector< atomic_type > &buffer)
T3DDatafield< T >::const_range_iterator iterator
CTParameter< C3DFVector > C3DFVectorParameter
3D vector parameter type
#define DECLARE_EXTERN(TYPE)
const C3DBounds & get_size() const
value_type get_interpol_val_at(const T3DVector< float > &p) const __attribute__((deprecated))
T3DDatafield< int32_t > C3DSIDatafield
a data field of 32 bit signed int values
void read_xslice_flat(size_t x, std::vector< atomic_type > &buffer) const
A class to hold data on a regular 2D grid.
Definition: 2d/datafield.hh:89
void put_data_line_z(int x, int y, const std::vector< T > &buffer)
void write_zslice_flat(size_t z, const std::vector< atomic_type > &buffer)
const_reference operator[](int i) const
#define DECLARE_EXTERN_ITERATORS(TYPE)
Definition: 3d/datafield.hh:41
T3DDatafield & operator=(const T3DDatafield &org)
void put_data_plane_xz(size_t y, const T2DDatafield< T > &p)
range_iterator_with_boundary_flag end_range_with_boundary_flags(const C3DBounds &begin, const C3DBounds &end)
void mask(const TMask &m)
a shortcut data type
const_reference operator()(size_t x, size_t y, size_t z) const
T2DDatafield< T > get_data_plane_yz(size_t x) const
iterator begin()
T3DDatafield< int16_t > C3DSSDatafield
a data field of 32 bit signed int values
void read_yslice_flat(size_t y, std::vector< atomic_type > &buffer) const
virtual ~T3DDatafield()
make sure the destructor is virtual
T3DDatafield< uint8_t > C3DUBDatafield
a data field of 8 bit int values
value_type get_avg()
range_iterator end_range(const C3DBounds &begin, const C3DBounds &end)
T2DDatafield< T > get_data_plane_xy(size_t z) const
size_type size() const
reference operator()(size_t x, size_t y, size_t z)
size_t get_plane_size_xy() const
bool holds_unique_data() const __attribute__((deprecated))
Definition: 3d/datafield.hh:97
iterator end()
void put_data_plane_yz(size_t x, const T2DDatafield< T > &p)
reference operator()(const C3DBounds &l)
T3DVector< Out > get_gradient(const T3DVector< float > &p) const
void put_data_line_x(int y, int z, const std::vector< T > &buffer)
T3DDatafield< float > C3DFDatafield
a data field of float values
T x
vector element
Definition: 3d/vector.hh:51
void get_data_line_z(int x, int y, std::vector< T > &buffer) const
Class of an attribute that holds data of type T.
Definition: attributes.hh:116
T3DDatafield< uint32_t > C3DUIDatafield
a data field of 32 bit unsigned int values
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36