My Project
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
68
69
72
73#ifdef __GNUC__
74#pragma GCC diagnostic pop
75#endif
76
81template <class T>
83{
84
85 typedef ::std::vector<typename __holder_type_dispatch<T>::type> data_array;
86
87public:
88
89
92 void make_single_ref() __attribute__((deprecated));
93
98 bool holds_unique_data()const __attribute__((deprecated))
99 {
100 return true;
101 }
102
103
105
107 typedef typename data_array::iterator iterator;
108 typedef typename data_array::const_iterator const_iterator;
109 typedef typename data_array::const_reference const_reference;
110 typedef typename data_array::reference reference;
111 typedef typename data_array::const_pointer const_pointer;
112 typedef typename data_array::pointer pointer;
113 typedef typename data_array::value_type value_type;
114 typedef typename data_array::size_type size_type;
115 typedef typename data_array::difference_type difference_type;
116 typedef typename atomic_data<value_type>::type atomic_type;
117 typedef range3d_iterator<iterator> range_iterator;
118 typedef range3d_iterator<const_iterator> const_range_iterator;
119
120 typedef range3d_iterator_with_boundary_flag<iterator> range_iterator_with_boundary_flag;
121 typedef range3d_iterator_with_boundary_flag<const_iterator> const_range_iterator_with_boundary_flag;
122
123 typedef C3DBounds dimsize_type;
125
136 {
137 friend class T3DDatafield<T>;
138 friend class ConstRange;
139 public:
140
142
144
146
147 private:
148 Range(const C3DBounds& start, const C3DBounds& end, T3DDatafield<T>& field);
149
150 iterator m_begin;
151 iterator m_end;
152 };
153
155 {
156 public:
157 friend class T3DDatafield<T>;
158
160
162
163 iterator end() const;
164
165 private:
166 ConstRange(const C3DBounds& start, const C3DBounds& end, const T3DDatafield<T>& field);
167
168 ConstRange(const Range& range);
169
170 iterator m_begin;
171 iterator m_end;
172 };
173
174
176
178 explicit T3DDatafield(const C3DBounds& _Size);
179
184 T3DDatafield(const C3DBounds& size, const T *data);
185
186
191 T3DDatafield(const C3DBounds& size, const data_array& data);
192
193
196
199
201 virtual ~T3DDatafield();
202
207 template <typename Out>
209
211 template <typename Out>
212 T3DVector<Out> get_gradient(size_t x, size_t y, size_t z) const;
213
215 template <typename Out>
216 T3DVector<Out> get_gradient(int index) const;
217
219 value_type get_interpol_val_at(const T3DVector<float >& p) const __attribute__((deprecated));
220
223 value_type get_block_avrg(const C3DBounds& Start, const C3DBounds& BlockSize) const;
224
230
233
235 const C3DBounds& get_size() const
236 {
237 return m_size;
238 }
239
241 void clear();
242
244 size_type size()const
245 {
246 return m_data.size();
247 }
248
250 void swap(T3DDatafield& other);
251
253 value_type get_avg();
254
257 value_type strip_avg();
258
260 const_reference operator()(size_t x, size_t y, size_t z) const
261 {
262 // Look if we are inside, and give reference, else give the zero
263 if (x < m_size.x && y < m_size.y && z < m_size.z) {
264 return m_data[x + m_size.x * (y + m_size.y * z)];
265 }
266
267 return Zero;
268 }
269
270
272 const_reference operator()(const C3DBounds& l)const
273 {
274 return (*this)(l.x, l.y, l.z);
275 }
276
278 reference operator()(size_t x, size_t y, size_t z)
279 {
280 // Look if we are inside, and give reference, else throw exception
281 // since write access is wanted
282 assert(x < m_size.x && y < m_size.y && z < m_size.z);
283 return m_data[x + m_size.x * (y + m_size.y * z)];
284 }
285
286
287
289 reference operator()(const C3DBounds& l)
290 {
291 return (*this)(l.x, l.y, l.z);
292 }
293
295 void get_data_line_x(int y, int z, std::vector<T>& buffer)const;
296
298 void get_data_line_y(int x, int z, std::vector<T>& buffer)const;
299
301 void get_data_line_z(int x, int y, std::vector<T>& buffer)const;
302
304 void put_data_line_x(int y, int z, const std::vector<T>& buffer);
305
307 void put_data_line_y(int x, int z, const std::vector<T>& buffer);
308
310 void put_data_line_z(int x, int y, const std::vector<T>& buffer);
311
313 template <class TMask>
314 void mask(const TMask& m);
315
329 void read_xslice_flat(size_t x, std::vector<atomic_type>& buffer) const;
330
343 void read_yslice_flat(size_t y, std::vector<atomic_type>& buffer) const;
344
357 void read_zslice_flat(size_t z, std::vector<atomic_type>& buffer) const;
358
363 void write_zslice_flat(size_t z, const std::vector<atomic_type>& buffer);
364
365
370 void write_yslice_flat(size_t y, const std::vector<atomic_type>& buffer);
371
376 void write_xslice_flat(size_t x, const std::vector<atomic_type>& buffer);
377
384
391
398
404 void put_data_plane_xy(size_t z, const T2DDatafield<T>& p);
405
411 void put_data_plane_yz(size_t x, const T2DDatafield<T>& p);
412
418 void put_data_plane_xz(size_t y, const T2DDatafield<T>& p);
419
421 const_iterator begin()const
422 {
423 return m_data.begin();
424 }
425
429 const_iterator begin_at(size_t x, size_t y, size_t z)const
430 {
431 return m_data.begin() + (z * m_size.y + y) * m_size.x + x;
432 }
433
434
438 const_iterator end()const
439 {
440 return m_data.end();
441 }
442
446 iterator begin()
447 {
448 return m_data.begin();
449 }
450
451 Range get_range(const C3DBounds& start, const C3DBounds& end);
452
453 ConstRange get_range(const C3DBounds& start, const C3DBounds& end) const;
454
457 range_iterator begin_range(const C3DBounds& begin, const C3DBounds& end);
458
460 range_iterator end_range(const C3DBounds& begin, const C3DBounds& end);
461
462
465 const_range_iterator begin_range(const C3DBounds& begin, const C3DBounds& end)const;
466
468 const_range_iterator end_range(const C3DBounds& begin, const C3DBounds& end)const;
469
470
472 range_iterator_with_boundary_flag begin_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end);
473
475 range_iterator_with_boundary_flag end_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end);
476
477
479 const_range_iterator_with_boundary_flag begin_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end)const;
480
482 const_range_iterator_with_boundary_flag end_range_with_boundary_flags(const C3DBounds& begin, const C3DBounds& end)const;
483
484
493 iterator begin_at(size_t x, size_t y, size_t z)
494 {
495 return m_data.begin() + (z * m_size.y + y) * m_size.x + x;
496 }
497
501 iterator end()
502 {
503 return m_data.end();
504 }
505
507 const_reference operator[](int i)const
508 {
509 return m_data[i];
510 }
511
515 reference operator[](int i)
516 {
517 return m_data[i];
518 }
519
520
522 size_t get_plane_size_xy()const
523 {
524 return m_xy;
525 };
526
527private:
529 C3DBounds m_size;
530
532 size_t m_xy;
533
535 data_array m_data;
536
538 static const value_type Zero;
539
540 static const size_t m_elements;
541
542};
543
546
549
552
555
558
561
564
567
570
571
574
577
580
582
584DECLARE_TYPE_DESCR(C3DBounds);
585DECLARE_TYPE_DESCR(C3DFVector);
586
587extern template class EXPORT_3D TAttribute<C3DFVector>;
589
590// some implementations
591
592template <class T>
593template <typename Out>
594T3DVector<Out> T3DDatafield<T>::get_gradient(size_t x, size_t y, size_t z) const
595{
596 const int sizex = m_size.x;
597
598 // Look if we are inside the used space
599 if (x - 1 < m_size.x - 2 && y - 1 < m_size.y - 2 && z - 1 < m_size.z - 2) {
600 // Lookup all neccessary Values
601 const T *H = &m_data[x + m_size.x * (y + m_size.y * z)];
602 return T3DVector<Out> (Out((H[1] - H[-1]) * 0.5),
603 Out((H[sizex] - H[-sizex]) * 0.5),
604 Out((H[m_xy] - H[-m_xy]) * 0.5));
605 }
606
607 return T3DVector<Out>();
608}
609
610
611template <class T>
612template <typename Out>
614{
615 const int sizex = m_size.x;
616 // Lookup all neccessary Values
617 const T *H = &m_data[hardcode];
618 return T3DVector<Out> (Out((H[1] - H[-1]) * 0.5),
619 Out((H[sizex] - H[-sizex]) * 0.5),
620 Out((H[m_xy] - H[-m_xy]) * 0.5));
621}
622
623
627template <>
628template <typename Out>
630{
631 // Lookup all neccessary Values
632 return T3DVector<Out> (Out((m_data[hardcode + 1] - m_data[hardcode - 1]) * 0.5),
633 Out((m_data[hardcode + m_size.x] - m_data[hardcode - m_size.x]) * 0.5),
634 Out((m_data[hardcode + m_xy] - m_data[hardcode - m_xy]) * 0.5));
635}
636
637template <class T>
638template <typename Out>
640{
641 // This will become really funny
642 const int sizex = m_size.x;
643 // Calculate the int coordinates near the POI
644 // and the distances
645 size_t x = size_t (p.x);
646 float dx = p.x - x;
647 float xm = 1 - dx;
648 size_t y = size_t (p.y);
649 float dy = p.y - y;
650 float ym = 1 - dy;
651 size_t z = size_t (p.z);
652 float dz = p.z - z;
653 float zm = 1 - dz;
654
655 // Look if we are inside the used space
656 if (x - 1 < m_size.x - 3 && y - 1 < m_size.y - 3 && z - 1 < m_size.z - 3 ) {
657 // Lookup all neccessary Values
658 const T *H000 = &m_data[x + sizex * y + m_xy * z];
659 const T *H_100 = &H000[-m_xy];
660 const T *H_101 = &H_100[1];
661 const T *H_110 = &H_100[sizex];
662 const T *H_111 = &H_110[1];
663 const T *H0_10 = &H000[-sizex];
664 const T *H0_11 = &H0_10[1];
665 const T *H00_1 = &H000[-1];
666 const T *H001 = &H000[ 1];
667 const T *H002 = &H000[ 2];
668 const T *H010 = &H000[sizex];
669 const T *H011 = &H010[ 1];
670 const T *H012 = &H010[ 2];
671 const T *H01_1 = &H010[-1];
672 const T *H020 = &H010[sizex];
673 const T *H021 = &H020[ 1];
674 const T *H100 = &H000[m_xy];
675 const T *H1_10 = &H100[sizex];
676 const T *H1_11 = &H1_10[1];
677 const T *H10_1 = &H100[-1];
678 const T *H101 = &H100[ 1];
679 const T *H102 = &H100[ 2];
680 const T *H110 = &H100[sizex];
681 const T *H111 = &H110[ 1];
682 const T *H112 = &H110[ 2];
683 const T *H11_1 = &H110[-1];
684 const T *H120 = &H110[sizex];
685 const T *H121 = &H120[ 1];
686 const T *H200 = &H100[m_xy];
687 const T *H201 = &H200[1];
688 const T *H210 = &H200[sizex];
689 const T *H211 = &H210[1];
690 // use trilinear interpolation to calc the gradient
691 return T3DVector<Out> (
692 Out((zm * (ym * (dx * (*H002 - *H000) + xm * (*H001 - *H00_1)) +
693 dy * (dx * (*H012 - *H010) + xm * (*H011 - *H01_1))) +
694 dz * (ym * (dx * (*H102 - *H100) + xm * (*H101 - *H10_1)) +
695 dy * (dx * (*H112 - *H110) + xm * (*H111 - *H11_1)))) * 0.5),
696 Out((zm * (ym * (xm * (*H010 - *H0_10) + dx * (*H011 - *H0_11)) +
697 dy * (xm * (*H020 - *H000) + dx * (*H021 - *H001))) +
698 dz * (ym * (xm * (*H110 - *H1_10) + dx * (*H111 - *H1_11)) +
699 dy * (xm * (*H120 - *H100) + dx * (*H121 - *H101)))) * 0.5),
700 Out((zm * (ym * (xm * (*H100 - *H_100) + dx * (*H101 - *H_101)) +
701 dy * (xm * (*H110 - *H_110) + dx * (*H111 - *H_111))) +
702 dz * (ym * (xm * (*H200 - *H000) + dx * (*H201 - *H001)) +
703 dy * (xm * (*H210 - *H010) + dx * (*H211 - *H011)))) * 0.5));
704 }
705
706 return T3DVector<Out>();
707}
708
709#ifdef __GNUC__
710#pragma GCC diagnostic push
711#ifndef __clang__
712#pragma GCC diagnostic ignored "-Wattributes"
713#endif
714#endif
715
716#define DECLARE_EXTERN(TYPE) \
717 extern template class EXPORT_3D T3DDatafield<TYPE>;
718
719
730
733
734extern template class EXPORT_3D CTParameter<C3DBounds>;
735extern template class EXPORT_3D CTParameter<C3DFVector>;
736extern template class EXPORT_3D TTranslator<C3DFVector>;
737extern template class EXPORT_3D TAttribute<C3DFVector>;
738
739
740#undef DECLARE_EXTERN
741
742#ifdef __GNUC__
743#pragma GCC diagnostic pop
744#endif
745
747
748#endif
#define DECLARE_EXTERN(TYPE)
TTranslator< C3DFVector > C3DFVectorTranslator
CTParameter< C3DBounds > C3DBoundsParameter
3D size parameter type
T3DDatafield< uint32_t > C3DUIDatafield
a data field of 32 bit unsigned int values
T3DDatafield< int32_t > C3DSIDatafield
a data field of 32 bit signed int values
T3DDatafield< int16_t > C3DSSDatafield
a data field of 32 bit signed int values
CTParameter< C3DFVector > C3DFVectorParameter
3D vector parameter type
T3DDatafield< uint16_t > C3DUSDatafield
a data field of 32 bit unsigned int values
T3DDatafield< uint64_t > C3DULDatafield
a data field of 32 bit unsigned int values
#define DECLARE_EXTERN_ITERATORS(TYPE)
Definition: 3d/datafield.hh:41
T3DDatafield< int8_t > C3DSBDatafield
a data field of 8 bit int values
T3DDatafield< bool > C3DBitDatafield
a data field of float values
T3DDatafield< int64_t > C3DLDatafield
a data field of 32 bit signed int values
T3DDatafield< uint8_t > C3DUBDatafield
a data field of 8 bit int values
T3DDatafield< float > C3DFDatafield
a data field of float values
Generic type of a complex paramter.
Definition: parameter.hh:171
A class to hold data on a regular 2D grid.
Definition: 2d/datafield.hh:90
T3DDatafield< T >::const_range_iterator iterator
iterator end() const
iterator begin() const
a shortcut data type
T3DDatafield< T >::range_iterator iterator
A templated class of a 3D data field.
Definition: 3d/datafield.hh:83
T2DDatafield< T > get_data_plane_xz(size_t y) const
void put_data_plane_xy(size_t z, const T2DDatafield< T > &p)
void write_zslice_flat(size_t z, const std::vector< atomic_type > &buffer)
size_t get_plane_size_xy() const
ConstRange get_range(const C3DBounds &start, const C3DBounds &end) const
const C3DBounds & get_size() const
void read_xslice_flat(size_t x, std::vector< atomic_type > &buffer) const
reference operator()(const C3DBounds &l)
T3DDatafield(T3DDatafield< T > &&org)
void mask(const TMask &m)
range_iterator begin_range(const C3DBounds &begin, const C3DBounds &end)
Range get_range(const C3DBounds &start, const C3DBounds &end)
value_type get_avg()
const_reference operator[](int i) const
T2DDatafield< T > get_data_plane_xy(size_t z) const
T3DVector< Out > get_gradient(const T3DVector< float > &p) const
const_range_iterator end_range(const C3DBounds &begin, const C3DBounds &end) const
const_reference operator()(size_t x, size_t y, size_t z) const
value_type strip_avg()
void put_data_line_z(int x, int y, const std::vector< T > &buffer)
range_iterator_with_boundary_flag begin_range_with_boundary_flags(const C3DBounds &begin, const C3DBounds &end)
range_iterator_with_boundary_flag end_range_with_boundary_flags(const C3DBounds &begin, const C3DBounds &end)
reference operator()(size_t x, size_t y, size_t z)
void write_yslice_flat(size_t y, const std::vector< atomic_type > &buffer)
const_reference operator()(const C3DBounds &l) const
void put_data_plane_xz(size_t y, const T2DDatafield< T > &p)
iterator begin_at(size_t x, size_t y, size_t z)
const_iterator begin_at(size_t x, size_t y, size_t z) const
void write_xslice_flat(size_t x, const std::vector< atomic_type > &buffer)
T3DVector< Out > get_gradient(int index) const
size_type size() const
void make_single_ref() __attribute__((deprecated))
T3DDatafield(const T3DDatafield< T > &org)
iterator end()
void get_data_line_x(int y, int z, std::vector< T > &buffer) const
value_type get_interpol_val_at(const T3DVector< float > &p) const __attribute__((deprecated))
const_range_iterator begin_range(const C3DBounds &begin, const C3DBounds &end) const
T3DDatafield(const C3DBounds &_Size)
void get_data_line_z(int x, int y, std::vector< T > &buffer) const
void read_yslice_flat(size_t y, std::vector< atomic_type > &buffer) const
void put_data_line_y(int x, int z, const std::vector< T > &buffer)
T3DDatafield & operator=(const T3DDatafield &org)
const_iterator begin() const
void swap(T3DDatafield &other)
swap the data ofthis 3DDatafield with another one
void read_zslice_flat(size_t z, std::vector< atomic_type > &buffer) const
virtual ~T3DDatafield()
make sure the destructor is virtual
const_iterator end() const
iterator begin()
T2DDatafield< T > get_data_plane_yz(size_t x) const
reference operator[](int i)
void put_data_plane_yz(size_t x, const T2DDatafield< T > &p)
const_range_iterator_with_boundary_flag begin_range_with_boundary_flags(const C3DBounds &begin, const C3DBounds &end) const
T3DDatafield(const C3DBounds &size, const data_array &data)
void get_data_line_y(int x, int z, std::vector< T > &buffer) const
void put_data_line_x(int y, int z, const std::vector< T > &buffer)
T3DDatafield(const C3DBounds &size, const T *data)
value_type get_block_avrg(const C3DBounds &Start, const C3DBounds &BlockSize) const
const_range_iterator_with_boundary_flag end_range_with_boundary_flags(const C3DBounds &begin, const C3DBounds &end) const
range_iterator end_range(const C3DBounds &begin, const C3DBounds &end)
T3DVector< Out > get_gradient(size_t x, size_t y, size_t z) const
T y
vector element
Definition: 3d/vector.hh:54
T z
vector element
Definition: 3d/vector.hh:56
T x
vector element
Definition: 3d/vector.hh:52
Class of an attribute that holds data of type T.
Definition: attributes.hh:119
Generic string vs. attribute translator singleton.
Definition: attributes.hh:518
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:44
a 3D iterator that knows its position in the 3D grid ans supports iterating over sub-ranges
Definition: 3d/iterator.hh:191
#define EXPORT_3D
Definition: defines3d.hh:45
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36