OpenWalnut  1.5.0dev
WMMergeComponentsToVector.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 <memory>
26 #include <string>
27 #include <vector>
28 
29 #include "WMMergeComponentsToVector.h"
30 #include "core/common/WPropertyHelper.h"
31 #include "core/dataHandler/WDataHandler.h"
32 #include "core/kernel/WKernel.h"
33 
34 // This line is needed by the module loader to actually find your module. You need to add this to your module too. Do NOT add a ";" here.
35 W_LOADABLE_MODULE( WMMergeComponentsToVector )
36 
38  WModule()
39 {
40 }
41 
43 {
44  // Cleanup!
45 }
46 
47 std::shared_ptr< WModule > WMMergeComponentsToVector::factory() const
48 {
49  return std::shared_ptr< WModule >( new WMMergeComponentsToVector() );
50 }
51 
52 const std::string WMMergeComponentsToVector::getName() const
53 {
54  return "Merge Components To Vector";
55 }
56 
58 {
59  return "Merge components to vector field.";
60 }
61 
63 {
64  // the dataset to process. Only accept scalar data.
65  m_scalarInX = WModuleInputData< WDataSetScalar >::createAndAdd( shared_from_this(), "X", "The X component field."
66  "Needs to be in the same grid as the others." );
67 
68  m_scalarInY = WModuleInputData< WDataSetScalar >::createAndAdd( shared_from_this(), "Y", "The Y component field."
69  "Needs to be in the same grid as the others." );
70 
71  m_scalarInZ = WModuleInputData< WDataSetScalar >::createAndAdd( shared_from_this(), "Z", "The Z component field."
72  "Needs to be in the same grid as the others." );
73 
74  // output vector data
75  m_vectorOut = WModuleOutputData< WDataSetVector >::createAndAdd( shared_from_this(), "merged", "The vector dataset" );
76 
77  // call WModule's initialization
79 }
80 
82 {
83  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
84 
85  // call WModule's initialization
87 }
88 
90 {
91  // get notified about data changes
92  m_moduleState.setResetable( true, true );
93  m_moduleState.add( m_scalarInX->getDataChangedCondition() );
94  m_moduleState.add( m_scalarInY->getDataChangedCondition() );
95  m_moduleState.add( m_scalarInZ->getDataChangedCondition() );
96  // Remember the condition provided to some properties in properties()? The condition can now be used with this condition set.
98 
99  ready();
100 
101  // main loop
102  while( !m_shutdownFlag() )
103  {
104  debugLog() << "Waiting ...";
106 
107  // woke up since the module is requested to finish?
108  if( m_shutdownFlag() )
109  {
110  break;
111  }
112 
113  // To query whether an input was updated, simply ask the input:
114  bool dataUpdated = m_scalarInX->handledUpdate() ||
115  m_scalarInY->handledUpdate() ||
116  m_scalarInZ->handledUpdate();
117 
118  std::shared_ptr< WDataSetScalar > dataSetX = m_scalarInX->getData();
119  std::shared_ptr< WDataSetScalar > dataSetY = m_scalarInY->getData();
120  std::shared_ptr< WDataSetScalar > dataSetZ = m_scalarInZ->getData();
121 
122  bool dataValid = ( dataSetX && dataSetY && dataSetZ );
123 
124  // reset output if input was reset/disconnected
125  if( !dataValid )
126  {
127  debugLog() << "Resetting output.";
128  m_vectorOut->reset();
129  continue;
130  }
131  if( dataValid && !dataUpdated )
132  {
133  continue;
134  }
135 
136  // loop through each voxel
137  std::shared_ptr< WGridRegular3D > gridX = std::dynamic_pointer_cast< WGridRegular3D >( dataSetX->getGrid() );
138  std::shared_ptr< WGridRegular3D > gridY = std::dynamic_pointer_cast< WGridRegular3D >( dataSetY->getGrid() );
139  std::shared_ptr< WGridRegular3D > gridZ = std::dynamic_pointer_cast< WGridRegular3D >( dataSetZ->getGrid() );
140  if( !( gridX && gridY && gridZ ) )
141  {
142  errorLog() << "Only regular 3D grids allowed.";
143  continue;
144  }
145 
146  // ensure the grids are the same
147  if( !( ( *gridX ) == ( *gridY ) ) || !( ( *gridX ) == ( *gridZ ) ) )
148  {
149  errorLog() << "Grids do not match.";
150  continue;
151  }
152 
153  // prepare progress indicators
154  std::shared_ptr< WProgress > progress( new WProgress( "Processing", dataSetX->getValueSet()->rawSize() ) );
155  m_progress->addSubProgress( progress );
156 
157  // FIXME: this should be done using visitors, making it data type invariant. For now, using doubles all the time is enough
158  if( !( ( dataSetX->getValueSet()->rawSize() == dataSetY->getValueSet()->rawSize() ) &&
159  ( dataSetX->getValueSet()->rawSize() == dataSetZ->getValueSet()->rawSize() ) ) )
160  {
161  errorLog() << "Value set sizes do not match.";
162  continue;
163  }
164 
165  // create target valueset
166  std::shared_ptr< std::vector< double > > data( new std::vector< double >() );
167  data->reserve( dataSetX->getValueSet()->rawSize() * 3 );
168 
169  for( size_t i = 0; i < dataSetX->getValueSet()->rawSize(); ++i )
170  {
171  double x = dataSetX->getValueSet()->getScalarDouble( i );
172  double y = dataSetY->getValueSet()->getScalarDouble( i );
173  double z = dataSetZ->getValueSet()->getScalarDouble( i );
174 
175  data->push_back( x );
176  data->push_back( y );
177  data->push_back( z );
178 
179  ++( *progress );
180  }
181 
182  // create valueset, dataset and update
183  std::shared_ptr< WValueSetBase > vs( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
184  WDataSetVector::SPtr ds( new WDataSetVector( vs, gridX ) );
185  m_vectorOut->updateData( ds );
186 
187  // work done
188  progress->finish();
189  m_progress->removeSubProgress( progress );
190 
191  debugLog() << "Done";
192  }
193 }
194 
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
This data set type contains vectors as values.
std::shared_ptr< WDataSetVector > SPtr
shared_ptr abbreviation
This modules takes several scalar inputs and merges them to a vector dataset.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
virtual const std::string getName() const
Gives back the name of this module.
WMMergeComponentsToVector()
Default constructor.
virtual void properties()
Initialize the properties for this module.
virtual void connectors()
Initialize the connectors this module is using.
std::shared_ptr< WModuleInputData< WDataSetScalar > > m_scalarInY
An input connector used to get datasets from other modules.
std::shared_ptr< WModuleInputData< WDataSetScalar > > m_scalarInX
An input connector used to get datasets from other modules.
std::shared_ptr< WModuleOutputData< WDataSetVector > > m_vectorOut
The output connector used to provide the calculated data to other modules.
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
virtual ~WMMergeComponentsToVector()
Destructor.
virtual const std::string getDescription() const
Provide description.
virtual void moduleMain()
Entry point after loading the module.
std::shared_ptr< WModuleInputData< WDataSetScalar > > m_scalarInZ
An input connector used to get datasets from other modules.
static PtrType createAndAdd(std::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this in data connector with proper type and add it to ...
static PtrType createAndAdd(std::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this out data connector with proper type and add it to...
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
wlog::WStreamedLogger errorLog() const
Logger instance for comfortable error logging.
Definition: WModule.cpp:570
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
Definition: WModule.h:652
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
Class managing progress inside of modules.
Definition: WProgress.h:42
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
Base Class for all value set types.
Definition: WValueSet.h:47