Commit a6831840 authored by Mathias Goldau's avatar Mathias Goldau

[CHANGE] Removed saving and "run"-button from the culling module, renamed...

[CHANGE] Removed saving and "run"-button from the culling module, renamed connectors and rearranged documentation.
parent 264447dd
......@@ -86,7 +86,7 @@ const char** WMDetTractClustering::getXPMIcon() const
void WMDetTractClustering::moduleMain()
{
m_moduleState.setResetable( true, true ); // modules state remembers fired events while not waiting
m_moduleState.add( m_tractInput->getDataChangedCondition() );
m_moduleState.add( m_tractIC->getDataChangedCondition() );
m_moduleState.add( m_update );
ready();
......@@ -100,14 +100,14 @@ void WMDetTractClustering::moduleMain()
break;
}
if( !m_tractInput->getData().get() ) // ok, the output has not yet sent data
if( !m_tractIC->getData().get() ) // ok, the output has not yet sent data
{
continue;
}
if( m_rawTracts != m_tractInput->getData() ) // in case data has changed
if( m_rawTracts != m_tractIC->getData() ) // in case data has changed
{
m_rawTracts = m_tractInput->getData();
m_rawTracts = m_tractIC->getData();
boost::shared_ptr< WProgress > convertProgress( new WProgress( "Converting tracts", 1 ) );
m_progress->addSubProgress( convertProgress );
m_tracts = boost::shared_ptr< WDataSetFiberVector >( new WDataSetFiberVector( m_rawTracts ) );
......@@ -174,7 +174,7 @@ void WMDetTractClustering::updateOutput()
warnLog() << "Invalid cluster ID for output selected: " << m_clusterOutputID->get() << " using default ID 0";
m_clusterOutputID->set( 0, true );
}
m_output->updateData( boost::shared_ptr< WFiberCluster >( new WFiberCluster( m_clusters[ m_clusterOutputID->get() ] ) ) );
m_cluserOC->updateData( boost::shared_ptr< WFiberCluster >( new WFiberCluster( m_clusters[ m_clusterOutputID->get() ] ) ) );
}
void WMDetTractClustering::update()
......@@ -424,8 +424,8 @@ void WMDetTractClustering::meld( size_t qClusterID, size_t rClusterID )
void WMDetTractClustering::connectors()
{
m_tractInput = WModuleInputData< WDataSetFibers >::createAndAdd( shared_from_this(), "tractInput", "A deterministic tract dataset." );
m_output = WModuleOutputData< WFiberCluster >::createAndAdd( shared_from_this(), "clusterOutput", "A set of tract indices aka cluster" );
m_tractIC = WModuleInputData< WDataSetFibers >::createAndAdd( shared_from_this(), "tractInput", "A deterministic tract dataset." );
m_cluserOC = WModuleOutputData< WFiberCluster >::createAndAdd( shared_from_this(), "clusterOutput", "A set of tract indices aka cluster" );
WModule::connectors(); // call WModules initialization
}
......
......@@ -165,34 +165,122 @@ private:
*/
void updateOutput();
size_t m_lastTractsSize; //!< Last known number of tracts
bool m_dLtTableExists; //!< Flag whether there is already a dLt look up table or not.
std::vector< size_t > m_clusterIDs; //!< Stores the cluster id of every tract so it is fast to get the cluster of a given tract.
std::vector< WFiberCluster > m_clusters; //!< Stores all WFiberClusters
/**
* Last known number of tracts
*/
size_t m_lastTractsSize;
/**
* Flag whether there is already a dLt look up table or not.
*/
bool m_dLtTableExists;
/**
* Stores the cluster id of every tract so it is fast to get the cluster of a given tract.
*/
std::vector< size_t > m_clusterIDs;
/**
* Stores all WFiberClusters
*/
std::vector< WFiberCluster > m_clusters;
/**
* Minimum distance of points of two tracts which should be considered
*/
WPropDouble m_proximity_t;
/**
* Maximum distance of two tracts in one cluster.
*/
WPropDouble m_maxDistance_t;
/**
* All clusters up to this size will be discarded
*/
WPropInt m_minClusterSize;
/**
* Specifies which cluster should be connected to the Output
*/
WPropInt m_clusterOutputID;
/**
* Button to initiate clustering with the given properties
*/
WPropTrigger m_run;
WPropDouble m_proximity_t; //!< Minimum distance of points of two tracts which should be considered
WPropDouble m_maxDistance_t; //!< Maximum distance of two tracts in one cluster.
WPropInt m_minClusterSize; //!< All clusters up to this size will be discarded
WPropInt m_clusterOutputID; //!< Specifies which cluster should be connected to the Output
WPropTrigger m_run; //!< Button to initiate clustering with the given properties
// information properties
WPropInt m_numTracts; //!< Number of tracts given from input
WPropInt m_numUsedTracts; //!< Number of tracts used for rendering
WPropInt m_numClusters; //!< Number of clusters computed
WPropInt m_numValidClusters; //!< Number of clusters used for rendering
WPropString m_clusterSizes; //!< Sizes of the clusters
WPropBool m_useCuda; //!< If compiled with cuda choose whether to use cuda or cpu implementation
/**
* Number of tracts given from input
*/
WPropInt m_numTracts;
boost::shared_ptr< WDataSetFiberVector > m_tracts; //!< Reference to the WDataSetFiberVector object
boost::shared_ptr< WDataSetFibers > m_rawTracts; //!< Reference to the WDataSetFibers object
boost::shared_ptr< WModuleInputData< WDataSetFibers > > m_tractInput; //!< Input connector for a tract dataset.
boost::shared_ptr< WModuleOutputData< WFiberCluster > > m_output; //!< Output connector for the first cluster.
boost::shared_ptr< WMatrixSymDBL > m_dLtTable; //!< Distance matrix lookUpTable
/**
* Number of tracts used for rendering
*/
WPropInt m_numUsedTracts;
boost::shared_ptr< WCondition > m_update; //!< Used for register properties indicating a rerun of the moduleMain loop
/**
* Number of clusters computed
*/
WPropInt m_numClusters;
/**
* Number of clusters used for rendering
*/
WPropInt m_numValidClusters;
/**
* Sizes of the clusters
*/
WPropString m_clusterSizes;
/**
* If compiled with cuda choose whether to use cuda or cpu implementation
*/
WPropBool m_useCuda;
/**
* Reference to the WDataSetFiberVector object
*/
boost::shared_ptr< WDataSetFiberVector > m_tracts;
/**
* Reference to the WDataSetFibers object
*/
boost::shared_ptr< WDataSetFibers > m_rawTracts;
/**
* Input connector for a tract dataset.
*/
boost::shared_ptr< WModuleInputData< WDataSetFibers > > m_tractIC;
/**
* Output connector for the first cluster.
*/
boost::shared_ptr< WModuleOutputData< WFiberCluster > > m_cluserOC;
/**
* Distance matrix lookUpTable
*/
boost::shared_ptr< WMatrixSymDBL > m_dLtTable;
/**
* Used for register properties indicating a rerun of the moduleMain loop
*/
boost::shared_ptr< WCondition > m_update;
/**
* OSG node for this module.
*/
osg::ref_ptr< WGEManagedGroupNode > m_osgNode;
osg::ref_ptr< WGEManagedGroupNode > m_osgNode; //!< OSG node for this module.
/**
* Validates the output cluster ID!
......@@ -216,7 +304,10 @@ private:
*/
virtual bool accept( boost::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_INT > > property, WPVBaseTypes::PV_INT value );
private:
const std::vector< WFiberCluster >& m_clusters; //!< accept() need to look into the cluster array for max size constraint
/**
* accept() need to look into the cluster array for max size constraint
*/
const std::vector< WFiberCluster >& m_clusters;
};
/**
......
......@@ -22,29 +22,17 @@
//
//---------------------------------------------------------------------------
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
// Use filesystem version 2 for compatibility with newer boost versions.
#ifndef BOOST_FILESYSTEM_VERSION
#define BOOST_FILESYSTEM_VERSION 2
#endif
#include <boost/filesystem.hpp>
#include "core/common/datastructures/WFiber.h"
#include "core/common/WColor.h"
#include "core/common/WLogger.h"
#include "core/common/WProgress.h"
#include "core/common/WPropertyHelper.h"
#include "core/dataHandler/exceptions/WDHIOFailure.h"
#include "core/dataHandler/io/WWriterFiberVTK.h"
#include "core/dataHandler/WDataSetFibers.h"
#include "core/dataHandler/WDataSetFiberVector.h"
#include "core/dataHandler/WSubject.h"
#include "core/kernel/WKernel.h"
#include "WMDetTractCulling.xpm"
#include "core/kernel/WModuleInputData.h"
#include "core/kernel/WModuleOutputData.h"
#include "WMDetTractCulling.h"
#include "WMDetTractCulling.xpm"
// This line is needed by the module loader to actually find your module.
W_LOADABLE_MODULE( WMDetTractCulling )
......@@ -79,13 +67,14 @@ void WMDetTractCulling::moduleMain()
while( !m_shutdownFlag() ) // loop until the module container requests the module to quit
{
if( !m_tractIC->getData().get() ) // ok, the output has not yet sent data
if( !m_tractIC->getData().get() ) // ok, there is no valid data yet
{
m_moduleState.wait();
continue;
}
if( m_rawDataset != m_tractIC->getData() ) // in case data has changed
bool dataChanged = ( m_rawDataset != m_tractIC->getData() );
if( dataChanged ) // only convert if dataset has changed not, if just parameters have changed
{
m_rawDataset = m_tractIC->getData();
boost::shared_ptr< WProgress > convertProgress( new WProgress( "Converting tracts", 1 ) );
......@@ -95,18 +84,9 @@ void WMDetTractCulling::moduleMain()
convertProgress->finish();
}
if( m_savePath->get().string() == "/no/such/file" )
{
m_savePath->set( saveFileName( m_dataset->getFileName() ) );
}
if( m_run->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
{
infoLog() << "Start processing tracts";
infoLog() << "Start processing " << m_numTracts << " tracts";
cullOutTracts();
infoLog() << "Processing finished";
m_run->set( WPVBaseTypes::PV_TRIGGER_READY, false );
}
infoLog() << "Processing finished with " << m_tractOC->getData()->size() << " tracts left";
m_moduleState.wait();
}
......@@ -122,12 +102,8 @@ void WMDetTractCulling::connectors()
void WMDetTractCulling::properties()
{
m_dSt_culling_t = m_properties->addProperty( "Min tract distance", "If below, the shorter tract is culled out", 6.5 );
m_proximity_t = m_properties->addProperty( "Min point distance", "Min distance of points of two tracts which should be considered", 1.0 );
m_saveCulledCurves = m_properties->addProperty( "Save result", "If true the remaining tracts are save to a file", false );
m_savePath = m_properties->addProperty( "Save path", "Where to save the result", boost::filesystem::path( "/no/such/file" ) );
m_run = m_properties->addProperty( "Start culling", "Start", WPVBaseTypes::PV_TRIGGER_READY, m_recompute );
WPropertyHelper::PC_NOTEMPTY::addTo( m_savePath );
m_dSt_culling_t = m_properties->addProperty( "Min tract distance", "If below, the shorter tract is culled out", 6.5, m_recompute );
m_proximity_t = m_properties->addProperty( "Min point distance", "If below, point distance not considered for tract", 1.0, m_recompute );
m_numRemovedTracts = m_infoProperties->addProperty( "#Tracts removed", "Number of tracts beeing culled out", 0 );
m_numRemovedTracts->setMin( 0 );
m_numRemovedTracts->setMax( wlimits::MAX_INT32_T );
......@@ -160,7 +136,9 @@ void WMDetTractCulling::cullOutTracts()
boost::shared_ptr< WProgress > progress( new WProgress( "Tract culling", numTracts ) );
m_progress->addSubProgress( progress );
for( size_t q = 0; q < numTracts && !m_shutdownFlag(); ++q ) // loop over all tracts
// loop over all tracts abort when shutdown, parameters changed. ATM changes on the input dataset are not considered!
// TODO(math): consider changes on input dataset
for( size_t q = 0; q < numTracts && !( m_shutdownFlag() || m_proximity_t->changed() || m_dSt_culling_t->changed() ); ++q )
{
if( unusedTracts[q] )
{
......@@ -189,46 +167,18 @@ void WMDetTractCulling::cullOutTracts()
}
++*progress;
}
if( m_shutdownFlag() )
if( m_shutdownFlag() || m_proximity_t->changed() || m_dSt_culling_t->changed() ) // if parameters changed we have to start all over again
{
return; // abort requested
}
progress->finish();
saveGainedTracts( unusedTracts );
}
void WMDetTractCulling::saveGainedTracts( const std::vector< bool >& unusedTracts )
{
boost::shared_ptr< WProgress > eraseProgress( new WProgress( "Erasing tracts", unusedTracts.size() ) );
m_progress->addSubProgress( eraseProgress );
boost::shared_ptr< const WDataSetFiberVector > result = m_dataset->generateDataSetOutOfUsedFibers( unusedTracts );
m_tractOC->updateData( result->toWDataSetFibers() );
eraseProgress->finish();
m_numRemovedTracts->set( unusedTracts.size() - m_tractOC->getData()->size() );
boost::shared_ptr< WProgress > saveProgress( new WProgress( "Saving tracts", unusedTracts.size() ) );
m_progress->addSubProgress( saveProgress );
if( m_saveCulledCurves->get() )
{
try
{
WWriterFiberVTK w( m_savePath->get(), true );
w.writeFibs( result );
}
catch( const WDHIOFailure& e )
{
errorLog() << "While writing tracts to file: " << e.what();
}
}
saveProgress->finish();
}
boost::filesystem::path WMDetTractCulling::saveFileName( std::string dataFileName ) const
{
std::stringstream newExtension;
newExtension << std::fixed << std::setprecision( 2 );
newExtension << ".pt-" << m_proximity_t->get() << ".dst-" << m_dSt_culling_t->get() << ".fib";
boost::filesystem::path tractFileName( dataFileName );
return tractFileName.replace_extension( newExtension.str() );
m_numRemovedTracts->set( m_dataset->size() - result->size() );
}
......@@ -30,11 +30,12 @@
#include <boost/shared_ptr.hpp>
#include "core/common/datastructures/WFiber.h"
#include "core/common/WFlag.h"
#include "core/dataHandler/WDataSetFiberVector.h"
#include "core/kernel/WModule.h"
#include "core/kernel/WModuleInputData.h"
class WDataSetFiberVector;
class WDataSetFibers;
template<class T> class WModuleInputData;
template<class T> class WModuleOutputData;
/**
* Removes deterministic tracts and therefore implements a preprocessing step
......@@ -108,24 +109,6 @@ protected:
*/
virtual void cullOutTracts();
/**
* Generates new data set out of the tracts which are not marked "unused"
* and saves it in the file as given via the savePath property.
*
* \param unusedTracts Vector of bool marking tracts not to use with true.
*/
virtual void saveGainedTracts( const std::vector< bool >& unusedTracts );
/**
* Generates the file name for saving the culled tracts out of some
* culling parameters: the proximity threshold and the dSt distance.
*
* \param dataFileName The file name from which the data is loaded so only the extension will change
*
* \return Path in which to store the culled tracts.
*/
boost::filesystem::path saveFileName( std::string dataFileName ) const;
/**
* Input connector for a tract dataset.
*/
......@@ -161,21 +144,6 @@ protected:
*/
WPropDouble m_proximity_t;
/**
* If true, remaining tracts are saved to a file
*/
WPropBool m_saveCulledCurves;
/**
* Path where remaining tracts should be stored
*/
WPropFilename m_savePath;
/**
* Trigger button for starting the long time consuming culling operation
*/
WPropTrigger m_run;
/**
* Displays the number of tracts which are processed
*/
......@@ -197,7 +165,7 @@ inline const std::string WMDetTractCulling::getName() const
inline const std::string WMDetTractCulling::getDescription() const
{
return std::string( "Removes deterministic tracts from a WDataSetFiberVector" );
return std::string( "Removes deterministic tracts from a dataset." );
}
#endif // WMDETTRACTCULLING_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WMDETTRACTCULLING_TEST_H
#define WMDETTRACTCULLING_TEST_H
#include <string>
#include <cxxtest/TestSuite.h>
#include "../WMDetTractCulling.h"
/**
* Unit test some functions in the deterministic tract culling module.
*/
class WMDetTractCullingTest : public CxxTest::TestSuite
{
public:
/**
* The correct save path is ascertained by replacing the extension with a
* new suffix containing also the culling parameters.
*/
void testSaveFileNameGeneration( void )
{
WMDetTractCulling module;
module.properties();
module.m_proximity_t->setMax( 200 );
module.m_proximity_t->set( 123.454 );
std::cout << "XXX" << module.m_proximity_t->get() << std::endl;
module.m_dSt_culling_t->set( 78.9 );
std::string expected( "/no/such/file.pt-123.45.dst-78.90.fib" );
TS_ASSERT_EQUALS( module.saveFileName( "/no/such/file.fib" ).string(), expected );
}
/**
* If no extension is present then the new file name should be ascertained by just
* concatenating the new extension with parameters.
*/
void testSaveFileNameGenerationWithoutExtension( void )
{
WMDetTractCulling module;
module.properties();
std::string expected( "/no/such/file.pt-1.00.dst-6.50.fib" );
TS_ASSERT_EQUALS( module.saveFileName( "/no/such/file" ).string(), expected );
}
/**
* If the path is gained from Windows every thing should work too.
*/
void testSaveFileNameGenerationAlsoWorkingOnWindowsPaths( void )
{
WMDetTractCulling module;
module.properties();
std::string expected( "C:\\no\\such\\file.pt-1.00.dst-6.50.fib" );
TS_ASSERT_EQUALS( module.saveFileName( "C:\\no\\such\\file" ).string(), expected );
}
};
#endif // WMDETTRACTCULLING_TEST_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment