OpenWalnut  1.5.0dev
WValueSet.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WVALUESET_H
26 #define WVALUESET_H
27 
28 #include <cmath>
29 #include <cstddef>
30 #include <limits>
31 #include <memory>
32 #include <vector>
33 
34 
35 #include "../common/WAssert.h"
36 #include "../common/WLimits.h"
37 #include "../common/math/WValue.h"
38 #include "../common/math/linearAlgebra/WVectorFixed.h"
39 #include "WDataHandlerEnums.h"
40 #include "WValueSetBase.h"
41 
42 /**
43  * Base Class for all value set types.
44  * \ingroup dataHandler
45  */
46 template< typename T > class WValueSet : public WValueSetBase
47 {
48 /**
49  * Only UnitTests are allowed to be friends
50  */
51 friend class WValueSetTest;
52 
53 public:
54  /**
55  * The type of the single value in this value set.
56  */
57  typedef T ValueT;
58 
59  /**
60  * \class SubArray
61  *
62  * A helper class granting safe access to a certain part of the valueset.
63  */
64  class SubArray
65  {
66  public:
67  //! make the valueset a friend
68  friend class WValueSet;
69 
70  /**
71  * Destructor.
72  */
74  {
75  }
76 
77  /**
78  * Safe access. Only the const version is allowed.
79  *
80  * \param i The relative position of the element in the subarray's range.
81  *
82  * \note If i is not in ( 0, size - 1 ), the first element will be returned.
83  *
84  * \return the value
85  */
86  T const& operator[] ( std::size_t i ) const
87  {
88  return *( m_ptr + i * static_cast< std::size_t >( i < m_size ) );
89  }
90 
91  // use the standard copy constructor and operator
92  private:
93  /**
94  * Construct an object that allows safe access.
95  * (no access to elements not in the subarray's range).
96  * Only a valueset may construct a SubArray.
97  *
98  * \param p A pointer to the first element.
99  * \param size The size of the subarray.
100  */
101  SubArray( T const* const p, std::size_t size )
102  : m_ptr( p ),
103  m_size( size )
104  {
105  }
106 
107  //! the pointer to the first element
108  T const* const m_ptr;
109 
110  //! the size of the subarray
111  std::size_t const m_size;
112  };
113 
114  /**
115  * Constructs a value set with values of type T. Sets order and dimension
116  * to allow to interpret the values as tensors of a certain order and dimension.
117  * \param order tensor order of values stored in the value set
118  * \param dimension tensor dimension of values stored in the value set
119  * \param data the vector holding the raw data
120  * \param inDataType indicator telling us which dataType comes in
121  */
122  WValueSet( size_t order, size_t dimension, const std::shared_ptr< std::vector< T > > data, dataType inDataType )
123  : WValueSetBase( order, dimension, inDataType ),
124  m_data( data )
125  {
126  // calculate min and max
127  // Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ...
128  m_minimum = std::numeric_limits< T >::max();
129  m_maximum = std::numeric_limits< T >::min();
130  for( typename std::vector< T >::const_iterator iter = data->begin(); iter != data->end(); ++iter )
131  {
132  m_minimum = m_minimum > *iter ? *iter : m_minimum;
133  m_maximum = m_maximum < *iter ? *iter : m_maximum;
134  }
135  }
136 
137  /**
138  * Constructs a value set with values of type T. Sets order and dimension
139  * to allow to interpret the values as tensors of a certain order and dimension.
140  * \param order tensor order of values stored in the value set
141  * \param dimension tensor dimension of values stored in the value set
142  * \param data the vector holding the raw data
143  */
144  WValueSet( size_t order, size_t dimension, const std::shared_ptr< std::vector< T > > data )
145  : WValueSetBase( order, dimension, DataType< T >::type ),
146  m_data( data )
147  {
148  // calculate min and max
149  // Calculating this once simply ensures that it does not need to be recalculated in textures, histograms ...
150  m_minimum = std::numeric_limits< T >::max();
151  m_maximum = std::numeric_limits< T >::min();
152  for( typename std::vector< T >::const_iterator iter = data->begin(); iter != data->end(); ++iter )
153  {
154  m_minimum = m_minimum > *iter ? *iter : m_minimum;
155  m_maximum = m_maximum < *iter ? *iter : m_maximum;
156  }
157  }
158 
159  /**
160  * \return The number of tensors stored in this set.
161  */
162  virtual size_t size() const
163  {
164  switch( m_order )
165  {
166  case 0 : // scalar
167  WAssert( m_dimension == 1, "Although order zero, (dimension != 1) was found." );
168  return rawSize();
169  case 1 : // vector
170  WAssert( rawSize() % m_dimension == 0, "Raw size and dimension don't fit." );
171  return rawSize() / m_dimension;
172  case 2 : // matrix
173  WAssert( rawSize() % ( m_dimension * m_dimension ) == 0, "Raw size and dimension don't fit." );
174  return rawSize() / ( m_dimension * m_dimension );
175  default : // other
176  WAssert( false, "Unsupported tensor order." );
177  return 0;
178  }
179  }
180 
181  /**
182  * \return The number of integral types stored in this set.
183  */
184  virtual size_t rawSize() const
185  {
186  return ( *m_data.get() ).size();
187  }
188 
189  /**
190  * \param i id of the scalar to retrieve
191  * \return The i-th scalar stored in this value set. There are rawSize() such scalars.
192  */
193  virtual T getScalar( size_t i ) const
194  {
195  return ( *m_data.get() )[i];
196  }
197 
198  /**
199  * \param i id of the scalar to retrieve
200  * \return The i-th scalar stored in this value set. There are rawSize() such scalars.
201  */
202  virtual double getScalarDouble( size_t i ) const
203  {
204  return static_cast< double >( ( *m_data.get() )[i] );
205  }
206 
207  /**
208  * \param i id of the WValue to retrieve
209  * \return The i-th WValue stored in this value set. There are size() such scalars.
210  */
211  virtual WValue< double > getWValueDouble( size_t i ) const
212  {
213  return WValue< double >( getWValue( i ) );
214  }
215 
216  /**
217  * Get the i'th vector
218  *
219  * \param index the index number of the vector
220  *
221  * \return the vector
222  */
223  WVector3d getVector3D( size_t index ) const;
224 
225 
226  /**
227  * Get the i'th WValue with the dimension of WValueSet
228  *
229  * \param index the index number of the WValue
230  *
231  * \return a WValue with the dimension WValueSet
232  */
233  WValue< T > getWValue( size_t index ) const;
234 
235  /**
236  * Sometimes we need raw access to the data array, for e.g. OpenGL.
237  *
238  * \return the raw data pointer
239  */
240  const T * rawData() const
241  {
242  return &( *m_data.get() )[0];
243  }
244 
245  /**
246  * Sometimes we need raw access to the data vector.
247  *
248  * \return the data vector
249  */
250  const std::vector< T >* rawDataVectorPointer() const
251  {
252  return &( *m_data.get() );
253  }
254 
255  /**
256  * Request (read-) access object to a subarray of this valueset.
257  * The object returned by this function can be used as an array
258  * ( starting at index 0 ), whose elements are the data elements
259  * at positions start to ( including ) start + size - 1 of the valueset.
260  *
261  * \param start The position of the first element of the subarray.
262  * \param size The number of elements in the subarray.
263  * \return The subarray.
264  */
265  SubArray const getSubArray( std::size_t start, std::size_t size ) const
266  {
267  WAssert( start + size <= rawSize(), "" );
268  WAssert( size != 0, "" );
269  return SubArray( rawData() + start, size );
270  }
271 
272  /**
273  * This method returns the smallest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
274  * smallest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
275  *
276  * \return the smallest value in the data.
277  */
278  virtual double getMinimumValue() const
279  {
280  return m_minimum;
281  }
282 
283  /**
284  * This method returns the largest value in the valueset. It does not handle vectors, matrices and so on well. It simply returns the
285  * largest value in the data array. This is especially useful for texture scaling or other statistic tools (histograms).
286  *
287  * \return the largest value in the data.
288  */
289  virtual double getMaximumValue() const
290  {
291  return m_maximum;
292  }
293 
294  /**
295  * Calculates the needed number of integral values for a valueset with specified order and dimension for one voxel. The whole dataset will
296  * then be as large as the number of voxels multiplied by this value.
297  *
298  * \param oder desired tensor order.
299  * \param dimension desired dimension.
300  *
301  * \return the number of values needed
302  */
303  static size_t getRequiredRawSizePerVoxel( size_t oder, size_t dimension );
304 protected:
305  /**
306  * The smallest value in m_data.
307  */
309 
310  /**
311  * The largest value in m_data.
312  */
314 
315 private:
316  /**
317  * Stores the values of type T as simple array which never should be modified.
318  */
319  const std::shared_ptr< std::vector< T > > m_data; // WARNING: don't remove constness since &m_data[0] won't work anymore!
320 
321  /**
322  * Get a variant reference to this valueset (the reference is stored in the variant).
323  * \note Use this as a temporary object inside a function or something like that.
324  * \return var A variant reference.
325  */
326  virtual WValueSetVariant const getVariant() const
327  {
328  return WValueSetVariant( this );
329  }
330 };
331 
332 template< typename T > WVector3d WValueSet< T >::getVector3D( size_t index ) const
333 {
334  WAssert( m_order == 1 && m_dimension == 3, "WValueSet<T>::getVector3D only implemented for order==1, dim==3 value sets" );
335  WAssert( ( index + 1 ) * 3 <= m_data->size(), "index in WValueSet<T>::getVector3D too big" );
336  size_t offset = index * 3;
337  return WVector3d( ( *m_data )[offset], ( *m_data )[offset + 1], ( *m_data )[offset + 2] );
338 }
339 
340 template< typename T > WValue< T > WValueSet< T >::getWValue( size_t index ) const
341 {
342  WAssert( m_order == 1, "WValueSet<T>::getWValue only implemented for order==1 value sets" );
343  WAssert( ( index + 1 ) * m_dimension <= m_data->size(), "index in WValueSet<T>::getWValue too big" );
344 
345  size_t offset = index * m_dimension;
346 
347  WValue< T > result( m_dimension );
348 
349  // copying values
350  for( std::size_t i = 0; i < m_dimension; i++ )
351  result[i] = ( *m_data )[offset+i];
352 
353  return result;
354 }
355 
356 template< typename T >
358 {
359  // NOTE: std::pow works only for floating point types
360  size_t pow = 1;
361  for( size_t v = 0; v < oder; ++v )
362  {
363  pow *= dimension;
364  }
365 
366  return pow;
367 }
368 
369 #endif // WVALUESET_H
Abstract base class to all WValueSets.
Definition: WValueSetBase.h:60
const size_t m_dimension
The dimension of the tensors for this ValueSet.
const size_t m_order
The order of the tensors for this ValueSet.
virtual size_t dimension() const
virtual size_t order() const
UnitTests the WValueSet class.
A helper class granting safe access to a certain part of the valueset.
Definition: WValueSet.h:65
~SubArray()
Destructor.
Definition: WValueSet.h:73
std::size_t const m_size
the size of the subarray
Definition: WValueSet.h:111
SubArray(T const *const p, std::size_t size)
Construct an object that allows safe access.
Definition: WValueSet.h:101
T const & operator[](std::size_t i) const
Safe access.
Definition: WValueSet.h:86
T const *const m_ptr
the pointer to the first element
Definition: WValueSet.h:108
Base Class for all value set types.
Definition: WValueSet.h:47
T m_minimum
The smallest value in m_data.
Definition: WValueSet.h:308
virtual size_t size() const
Definition: WValueSet.h:162
WValue< T > getWValue(size_t index) const
Get the i'th WValue with the dimension of WValueSet.
Definition: WValueSet.h:340
WVector3d getVector3D(size_t index) const
Get the i'th vector.
Definition: WValueSet.h:332
SubArray const getSubArray(std::size_t start, std::size_t size) const
Request (read-) access object to a subarray of this valueset.
Definition: WValueSet.h:265
T m_maximum
The largest value in m_data.
Definition: WValueSet.h:313
const std::vector< T > * rawDataVectorPointer() const
Sometimes we need raw access to the data vector.
Definition: WValueSet.h:250
WValueSet(size_t order, size_t dimension, const std::shared_ptr< std::vector< T > > data, dataType inDataType)
Constructs a value set with values of type T.
Definition: WValueSet.h:122
virtual T getScalar(size_t i) const
Definition: WValueSet.h:193
WValueSet(size_t order, size_t dimension, const std::shared_ptr< std::vector< T > > data)
Constructs a value set with values of type T.
Definition: WValueSet.h:144
static size_t getRequiredRawSizePerVoxel(size_t oder, size_t dimension)
Calculates the needed number of integral values for a valueset with specified order and dimension for...
Definition: WValueSet.h:357
const T * rawData() const
Sometimes we need raw access to the data array, for e.g.
Definition: WValueSet.h:240
virtual WValueSetVariant const getVariant() const
Get a variant reference to this valueset (the reference is stored in the variant).
Definition: WValueSet.h:326
virtual WValue< double > getWValueDouble(size_t i) const
Definition: WValueSet.h:211
const std::shared_ptr< std::vector< T > > m_data
Stores the values of type T as simple array which never should be modified.
Definition: WValueSet.h:319
virtual double getMaximumValue() const
This method returns the largest value in the valueset.
Definition: WValueSet.h:289
T ValueT
The type of the single value in this value set.
Definition: WValueSet.h:57
virtual double getScalarDouble(size_t i) const
Definition: WValueSet.h:202
virtual double getMinimumValue() const
This method returns the smallest value in the valueset.
Definition: WValueSet.h:278
virtual size_t rawSize() const
Definition: WValueSet.h:184
Base class for all higher level values like tensors, vectors, matrices and so on.
Definition: WValue.h:41
dataType
Data types and number values taken from the nifti1.h, at this point it's unknown if it makes sense to...
An object that knows an appropriate dataType flag for the typename T.