OpenWalnut  1.5.0dev
WCsvConverter.cpp
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 #include <cmath>
26 #include <map>
27 #include <memory>
28 #include <string>
29 #include <vector>
30 
31 #include <core/common/datastructures/WFiber.h>
32 #include <core/dataHandler/WDataSetFiberVector.h>
33 
34 #include "WCsvConverter.h"
35 
36 WCsvConverter::WCsvConverter( WProtonData::SPtr protonData, std::shared_ptr< WPropertyStatus > propertyStatus,
37  WModule::SPtr colorBar )
38 {
39  if( protonData == nullptr || propertyStatus == nullptr || colorBar == nullptr )
40  {
41  throw WException( "Could not convert CSV data! Proton data, property status or color bar are missing!" );
42  }
43 
44  m_protonData = protonData;
45  m_propertyStatus = propertyStatus;
48  m_colorBar = colorBar;
49 
51 }
52 
53 std::shared_ptr< WDataSetFibers > WCsvConverter::getFibers()
54 {
55  return m_fibers;
56 }
57 
58 std::shared_ptr< WDataSetPoints > WCsvConverter::getPoints()
59 {
60  return m_points;
61 }
62 
63 std::shared_ptr< WDataSetPoints > WCsvConverter::getPointsAndData()
64 {
65  return m_pointsAndData;
66 }
67 
69 {
70  if( !m_protonData->isColumnAvailable( WSingleSelectorName::getX() ) ||
71  !m_protonData->isColumnAvailable( WSingleSelectorName::getY() ) ||
72  !m_protonData->isColumnAvailable( WSingleSelectorName::getZ() ) )
73  {
74  return;
75  }
76 
77  WDataSetCSV::ContentSPtr data = m_protonData->getCSVData();
78 
79  WColor plainColor = m_propertyStatus->getVisualizationPropertyHandler()->getColorSelection()->get( true );
80 
81  m_vectors->clear();
82  m_indexes->update( m_protonData );
83 
84  float maxEdep = wlimits::MIN_FLOAT;
85  float minEdep = wlimits::MAX_FLOAT;
86 
87  for( WDataSetCSV::Content::iterator dataRow = data->begin(); dataRow < data->end(); dataRow++ )
88  {
89  if( !checkConditionToPass( dataRow ) )
90  {
91  continue;
92  }
93 
94  if( m_protonData->isColumnAvailable( WSingleSelectorName::getEdep() ) )
95  {
96  float edep = stringToDouble( dataRow->at( m_indexes->getEdep() ) );
97 
98  if( m_propertyStatus->getVisualizationPropertyHandler()->getEnableClusterSize()->get() &&
99  ( getClusterSize( edep ) < 1.0 || getClusterSize( edep ) > 35.0 ) )
100  {
101  continue;
102  }
103  }
104 
105  addVertex( dataRow );
106  addColor( plainColor );
107  addEdepAndSize( dataRow, &maxEdep, &minEdep );
108  addEventID( dataRow );
109  }
110 
111  if( checkIfOutputIsNull() )
112  {
113  return;
114  }
115 
116  normalizeEdeps( m_vectors->getEdeps(), m_vectors->getColors(), maxEdep, minEdep );
117 
121 }
122 
123 std::shared_ptr< WDataSetSingle > WCsvConverter::getTransferFunction()
124 {
125  return m_transferFunction;
126 }
127 
128 std::shared_ptr< std::vector<unsigned char> > WCsvConverter::sampleTransferFunction()
129 {
130  std::shared_ptr< std::vector<unsigned char> > data( new std::vector<unsigned char>( 50 * 4 ) );
131 
132  WTransferFunction tf = m_propertyStatus->getVisualizationPropertyHandler()->getTransferFunction()->get( true );
133 
134  tf.sample1DTransferFunction( &( *data )[ 0 ], 50, 0.0, 1.0 );
135 
136  return data;
137 }
138 
139 void WCsvConverter::normalizeEdeps( SPFloatVector edeps, SPFloatVector colorArray, float maxEdep, float minEdep )
140 {
141  if( m_protonData->isColumnAvailable( WSingleSelectorName::getEdep() ) )
142  {
143  std::shared_ptr< std::vector< unsigned char > > data = sampleTransferFunction();
144 
145  setTransferFunction( data );
146 
147  bool clusterEnabled = m_propertyStatus->getVisualizationPropertyHandler()->getEnableClusterSize()->get();
148 
149  float maxClusterSize = clusterEnabled ? getClusterSize( maxEdep ) : maxEdep;
150  float minClusterSize = clusterEnabled ? getClusterSize( minEdep ) : minEdep;
151 
152  for( std::vector< float >::iterator currentEdep = edeps->begin();
153  currentEdep != edeps->end();
154  currentEdep++ )
155  {
156  float clusterSizeNormalized = clusterEnabled ? getClusterSize( *currentEdep ) : *currentEdep;
157  clusterSizeNormalized = ( clusterSizeNormalized - minClusterSize ) / ( maxClusterSize - minClusterSize );
158 
159  WAssert( clusterSizeNormalized >= 0 && clusterSizeNormalized <= 1, "The normalized energy deposition must be between 0 and 1" );
160 
161  m_vectors->getSizes()->push_back( clusterSizeNormalized );
162 
163  if( m_propertyStatus->getVisualizationPropertyHandler()->getColorFromEdep()->get() )
164  {
165  clusterSizeNormalized = static_cast< int >( 49 * clusterSizeNormalized );
166 
167  for( int i = 0; i < 4; i++ )
168  {
169  colorArray->push_back( data->at( clusterSizeNormalized * 4 + i ) / 255.0 );
170  }
171  }
172  }
173 
174  m_colorBar->getProperties()->getProperty( "Max scale value" )->set( 0.0 );
175  m_colorBar->getProperties()->getProperty( "Max scale value" )->set( maxClusterSize );
176  m_colorBar->getProperties()->getProperty( "Min scale value" )->set( minClusterSize );
177 
178  if( clusterEnabled )
179  {
180  m_colorBar->getProperties()->getProperty( "Description" )->set( std::string( "Clustersize " ) );
181  }
182  else
183  {
184  std::string columnName = m_protonData->getCSVHeader()->at( 0 ).at( m_indexes->getEdep() );
185  m_colorBar->getProperties()->getProperty( "Description" )->set( columnName + " " );
186  }
187 
188  bool activated = m_propertyStatus->getVisualizationPropertyHandler()->getColorFromEdep()->get();
189 
190  m_colorBar->getProperties()->getProperty( "active" )->toPropBool()->set( activated );
191  }
192 }
193 
194 bool WCsvConverter::checkConditionToPass( WDataSetCSV::Content::iterator dataRow )
195 {
196  if( dataRow->empty() )
197  {
198  return false;
199  }
200 
201  if( m_protonData->isColumnAvailable( WSingleSelectorName::getParentId() ) )
202  {
203  int PrimaryValue = stringToInt( dataRow->at( m_indexes->getParentID() ) );
204 
205  if( !m_propertyStatus->getFilterPropertyHandler()->getShowPrimaries()->get() && PrimaryValue == 0 )
206  {
207  return false;
208  }
209 
210  if( !m_propertyStatus->getFilterPropertyHandler()->getShowSecondaries()->get() && PrimaryValue != 0 )
211  {
212  return false;
213  }
214  }
215 
216  if( m_protonData->isColumnAvailable( WSingleSelectorName::getPDG() ) )
217  {
218  if( !m_propertyStatus->getFilterPropertyHandler()->isPDGTypeSelected(
219  ( int )stringToDouble( dataRow->at( m_indexes->getPDGEncoding( ) ) ) ) )
220  {
221  return false;
222  }
223  }
224 
225  if( m_protonData->isColumnAvailable( WSingleSelectorName::getEventId() ) )
226  {
227  if( dataRow->at( m_indexes->getEventID() ) == "NULL" )
228  {
229  return true;
230  }
231 
232  int eventID = stringToInt( dataRow->at( m_indexes->getEventID() ) );
233  if( eventID < m_propertyStatus->getEventIDLimitationPropertyHandler()->getMinCap()->get() ||
234  eventID > m_propertyStatus->getEventIDLimitationPropertyHandler()->getMaxCap()->get() )
235  {
236  return false;
237  }
238  }
239 
240  return true;
241 }
242 
243 void WCsvConverter::addVertex( WDataSetCSV::Content::iterator dataRow )
244 {
245  m_vectors->getVertices()->push_back( stringToDouble( dataRow->at( m_indexes->getPosX() ) ) );
246  m_vectors->getVertices()->push_back( stringToDouble( dataRow->at( m_indexes->getPosY() ) ) );
247  m_vectors->getVertices()->push_back( stringToDouble( dataRow->at( m_indexes->getPosZ() ) ) );
248 }
249 
250 void WCsvConverter::addColor( WColor plainColor )
251 {
252  if( !m_protonData->isColumnAvailable( WSingleSelectorName::getEdep() ) ||
253  !m_propertyStatus->getVisualizationPropertyHandler()->getColorFromEdep()->get() )
254  {
255  m_vectors->getColors()->push_back( plainColor[0] );
256  m_vectors->getColors()->push_back( plainColor[1] );
257  m_vectors->getColors()->push_back( plainColor[2] );
258  m_vectors->getColors()->push_back( plainColor[3] );
259  }
260 }
261 
262 void WCsvConverter::addEdepAndSize( WDataSetCSV::Content::iterator dataRow, float* maxEdep, float* minEdep )
263 {
264  if( !m_protonData->isColumnAvailable( WSingleSelectorName::getEdep() ) )
265  {
266  return;
267  }
268 
269  float edep = stringToDouble( dataRow->at( m_indexes->getEdep() ) );
270  if( edep > *maxEdep )
271  {
272  *maxEdep = edep;
273  }
274 
275  if( edep < *minEdep )
276  {
277  *minEdep = edep;
278  }
279 
280  m_vectors->getEdeps()->push_back( edep );
281 }
282 
284 {
285  size_t skippedPoints = 0;
286  std::shared_ptr< std::map< size_t, std::shared_ptr< WFiber > > > fibers( new std::map< size_t, std::shared_ptr< WFiber > >() );
287  std::shared_ptr< std::map< size_t, SPFloatVector > > colors( new std::map< size_t, SPFloatVector >() );
288 
289  for( size_t i = 0; i < m_vectors->getEventIDs()->size(); i++ )
290  {
291  size_t eID = m_vectors->getEventIDs()->at( i );
292  WPosition pos( m_vectors->getVertices()->at( i * 3 ), m_vectors->getVertices()->at( i * 3 + 1 ), m_vectors->getVertices()->at( i * 3 + 2 ) );
293 
294  std::shared_ptr< WFiber > fib;
295  SPFloatVector col;
296 
297  if( fibers->find( eID ) != fibers->end() )
298  {
299  fib = fibers->operator[]( eID );
300  col = colors->operator[]( eID );
301  }
302  else
303  {
304  fib = std::shared_ptr< WFiber >( new WFiber() );
305  col = SPFloatVector( new std::vector< float > );
306  fibers->operator[]( eID ) = fib;
307  colors->operator[]( eID ) = col;
308  }
309 
310  if( std::find( fib->begin(), fib->end(), pos ) == fib->end() )
311  {
312  fib->push_back( pos );
313  col->push_back( m_vectors->getColors()->at( i * 4 ) );
314  col->push_back( m_vectors->getColors()->at( i * 4 + 1 ) );
315  col->push_back( m_vectors->getColors()->at( i * 4 + 2 ) );
316  col->push_back( m_vectors->getColors()->at( i * 4 + 3 ) );
317  }
318  else
319  {
320  skippedPoints++;
321  }
322  }
323 
325  SPFloatVector cols = SPFloatVector( new std::vector< float > );
326  for( auto it = fibers->begin(); it != fibers->end(); it++ )
327  {
328  if( it->second->size() > 1 )
329  {
330  newDS->push_back( *( it->second ) );
331  SPFloatVector col = colors->operator[]( it->first );
332  cols->insert( cols->end(), col->begin(), col->end() );
333  }
334  }
335 
336  m_fibers = newDS->toWDataSetFibers();
337  if( m_fibers->getVertices()->size() == 0 )
338  {
339  // This is so it doesn't generate colors when there are no fibers, which would result in a module crash.
340  return;
341  }
342 
343  m_fibers->addColorScheme( cols, "Energy deposition", "Color fibers based on their energy." );
344  m_fibers->setSelectedColorScheme( 3 );
345 
346  if( skippedPoints > 0 )
347  {
348  wlog::warn( "WCsvConverter" ) << "Skipped " << skippedPoints << " duplicated points for \"WDataSetFibers\".";
349  }
350 }
351 
353 {
354  if( m_protonData->isColumnAvailable( WSingleSelectorName::getEdep() ) )
355  {
356  if( m_propertyStatus->getVisualizationPropertyHandler()->getSizesFromEdep()->get() )
357  {
358  m_points = std::shared_ptr< WDataSetPoints >(
359  new WDataSetPoints(
360  m_vectors->getVertices(),
361  m_vectors->getColors(),
362  std::shared_ptr< WValueSet< float > >( new WValueSet< float >( 0, 1, m_vectors->getSizes() ) )
363  )
364  );
365  return;
366  }
367  }
368  m_points = std::shared_ptr < WDataSetPoints >(
369  new WDataSetPoints(
370  m_vectors->getVertices(),
371  m_vectors->getColors()
372  )
373  );
374 }
375 
377 {
378  if( !m_protonData->isColumnAvailable( WSingleSelectorName::getEventId() ) )
379  {
380  m_fibers = std::shared_ptr< WDataSetFibers >(
381  new WDataSetFibers(
382  SPFloatVector( new std::vector< float >() ),
383  SPSizeVector( new std::vector< size_t >() ),
384  SPSizeVector( new std::vector< size_t >() ),
385  SPSizeVector( new std::vector< size_t >() )
386  )
387  );
388 
389  return;
390  }
391 
392  calculateFibers();
393 }
394 
396 {
397  bool edep = m_propertyStatus->getOutputPropertyHandler()->getEnergyDeposition()->get() &&
398  m_protonData->isColumnAvailable( WSingleSelectorName::getEdep() );
399 
400  bool eventID = m_propertyStatus->getOutputPropertyHandler()->getEventID()->get() &&
401  m_protonData->isColumnAvailable( WSingleSelectorName::getEventId() );
402 
403  if( edep && eventID )
404  {
405  std::tuple< SPFloatVector, SPSizeVector > data = std::make_tuple( m_vectors->getEdeps(), m_vectors->getEventIDs() );
406  m_pointsAndData = WDataSetPoints::SPtr( new WDataSetPoints( m_vectors->getVertices(), m_vectors->getColors(), data ) );
407  }
408  else if( edep )
409  {
410  std::tuple< SPFloatVector > data = std::make_tuple( m_vectors->getEdeps() );
411  m_pointsAndData = WDataSetPoints::SPtr( new WDataSetPoints( m_vectors->getVertices(), m_vectors->getColors(), data ) );
412  }
413  else if( eventID )
414  {
415  std::tuple< SPSizeVector > data = std::make_tuple( m_vectors->getEventIDs() );
416  m_pointsAndData = WDataSetPoints::SPtr( new WDataSetPoints( m_vectors->getVertices(), m_vectors->getColors(), data ) );
417  }
418 }
419 
420 void WCsvConverter::addEventID( WDataSetCSV::Content::iterator dataRow )
421 {
422  if( m_protonData->isColumnAvailable( WSingleSelectorName::getEventId() ) )
423  {
424  if( dataRow->at( m_indexes->getEventID() ) == "NULL" )
425  {
426  return;
427  }
428 
429  m_vectors->getEventIDs()->push_back( stringToInt( dataRow->at( m_indexes->getEventID() ) ) );
430  }
431 }
432 
433 void WCsvConverter::setTransferFunction( std::shared_ptr< std::vector<unsigned char> > data )
434 {
435  std::shared_ptr< WValueSetBase > newValueSet( new WValueSet<unsigned char>( 1, 4, data, W_DT_UNSIGNED_CHAR ) );
436 
437  WGridTransformOrtho transform;
438  std::shared_ptr< WGridRegular3D > newGrid( new WGridRegular3D( 50, 1, 1, transform ) );
439  std::shared_ptr< WDataSetSingle > newData( new WDataSetSingle( newValueSet, newGrid ) );
440 
441  m_transferFunction = newData;
442 }
443 
445 {
446  if( m_vectors->getVertices()->empty() )
447  {
448  m_points = NULL;
449  m_fibers = NULL;
450  m_pointsAndData = NULL;
451  return true;
452  }
453  return false;
454 }
455 
456 float WCsvConverter::getClusterSize( float edep )
457 {
458  return 7.6626f * powf( edep * 40.0f, 0.420307f );
459 }
460 
461 float WCsvConverter::stringToDouble( std::string str )
462 {
463  try
464  {
465  return boost::lexical_cast< double >( str );
466  }
467  catch( const boost::bad_lexical_cast &e )
468  {
469  std::string errorMessage = "The selected column has an incorrect format. Received: " + str + ". " +
470  "Required: Numbers are expected. " +
471  std::string( e.what() );
472 
473  throw WException( errorMessage );
474  }
475 }
476 
477 int WCsvConverter::stringToInt( std::string str )
478 {
479  //lexical_cast <int> cannot cast numbers as exponential notation, so we take this way.
480  float numAsDouble = stringToDouble( str );
481  return ( int )numAsDouble;
482 }
Holds the indexes of the columns and is able to update them.
std::shared_ptr< WConverterIndexes > SPtr
A shared_ptr to this class.
Holds the vectors that store the data for the points and fibers.
std::shared_ptr< WConverterVectors > SPtr
A shared_ptr to this class.
WPropertyStatus::SPtr m_propertyStatus
includes all property groups
std::shared_ptr< WDataSetPoints > getPoints()
Getter.
WModule::SPtr m_colorBar
Stores reference to the given transfer function color bar module.
void addEdepAndSize(WDataSetCSV::Content::iterator dataRow, float *maxEdep, float *minEdep)
Create edep and sizes for point/fiber renderer.
void setTransferFunction(std::shared_ptr< std::vector< unsigned char > > data)
Creates output for transfer function.
void normalizeEdeps(SPFloatVector edeps, SPFloatVector colorArray, float maxEdep, float minEdep)
Normalize energy deposition values to use as RGB values.
std::shared_ptr< std::vector< float > > SPFloatVector
represents a std::shared_ptr to a vector containing a vector of floats.
Definition: WCsvConverter.h:72
void addVertex(WDataSetCSV::Content::iterator dataRow)
Create vertex for point/fiber renderer.
std::shared_ptr< std::vector< size_t > > SPSizeVector
represents a std::shared_ptr to a vector containing a vector of size_t.
Definition: WCsvConverter.h:77
void addEventID(WDataSetCSV::Content::iterator dataRow)
Create eventID for Fiber renderer.
std::shared_ptr< WDataSetSingle > m_transferFunction
Stores the currently mapped transfer function.
void createOutputPointsAndData()
Create the points and selected data for Point Connector.
std::shared_ptr< WDataSetFibers > m_fibers
Stores information for the fiber display.
WCsvConverter(WProtonData::SPtr protonData, std::shared_ptr< WPropertyStatus > propertyStatus, WModule::SPtr colorBar)
Initializes the vectors, indices and transfer function color bar Calls setOutputFromCSV.
std::shared_ptr< WDataSetPoints > m_points
Stores information for the point renderer.
WProtonData::SPtr m_protonData
Stores information form csv content.
float stringToDouble(std::string str)
checks whether the string is a number (double)
bool checkConditionToPass(WDataSetCSV::Content::iterator dataRow)
checks whether the requirements are fulfilled.
void calculateFibers()
calculate the property of WDataSetFiber (index, length, verticesReverse)
std::shared_ptr< WDataSetPoints > m_pointsAndData
Stores information for the point Conncetor.
int stringToInt(std::string str)
checks whether the string is a number (int)
void setOutputFromCSV()
Create outputs, so it can be displayed by the fiber display and the point renderer.
float getClusterSize(float edep)
Computes the cluster size.
void addColor(WColor plainColor)
Create color for point/Fiber renderer.
bool checkIfOutputIsNull()
the cast value from string to float
std::shared_ptr< WDataSetSingle > getTransferFunction()
Getter.
std::shared_ptr< WDataSetPoints > getPointsAndData()
Getter.
void createOutputPoints()
Create the points for points renderer.
WConverterVectors::SPtr m_vectors
Stores points for point and fiber renderer.
WConverterIndexes::SPtr m_indexes
Stores indexes for fiber renderer.
std::shared_ptr< std::vector< unsigned char > > sampleTransferFunction()
Computes gradient vector from transfer function specified in visualization properties.
void createOutputFibers()
Create the fibers for fiber renderer.
std::shared_ptr< WDataSetFibers > getFibers()
Getter.
std::shared_ptr< std::vector< std::vector< std::string > > > ContentSPtr
represents a pointer to the Content
Definition: WDataSetCSV.h:52
Represents a simple set of WFibers.
std::shared_ptr< WDataSetFiberVector > SPtr
Short hand for a std::shared_ptr on such classes.
Represents a simple set of WFibers.
Dataset to store a bunch of points without order or topology.
std::shared_ptr< WDataSetPoints > SPtr
Pointer to dataset.
A data set consisting of a set of values based on a grid.
Basic exception handler.
Definition: WException.h:39
Represents a neural pathway.
Definition: WFiber.h:40
A grid that has parallelepiped cells which all have the same proportion.
Implements an orthogonal grid transformation.
std::shared_ptr< WModule > SPtr
Shared pointer to a WModule.
Definition: WModule.h:106
This only is a 3d double vector.
std::shared_ptr< WProtonData > SPtr
shared_ptr that points to itself
Definition: WProtonData.h:52
static std::string getX()
getter
static std::string getY()
getter
static std::string getZ()
getter
static std::string getEdep()
getter
static std::string getPDG()
getter
static std::string getParentId()
getter
static std::string getEventId()
getter
A class that stores a 1D transfer function which consists of a linear interpolation of alpha and colo...
void sample1DTransferFunction(unsigned char *array, int width, double min, double max) const
sample/render the transfer function linearly between min and max in an RGBA texture.
Base Class for all value set types.
Definition: WValueSet.h:47
const float MIN_FLOAT
Positive minimum float value.
Definition: WLimits.cpp:37
const float MAX_FLOAT
Maximum float value.
Definition: WLimits.cpp:32
WStreamedLogger warn(const std::string &source)
Logging a warning message.
Definition: WLogger.h:309