Commit 0aaddaad authored by schurade's avatar schurade
Browse files

[Merge] with 150cfe5acbe037ffd796af541a93d1253dacb14e

parents 10fc733c 346b397f
......@@ -22,24 +22,95 @@
//
//---------------------------------------------------------------------------
#include <algorithm>
#include <iterator>
#include <fstream>
#include <map>
#include <set>
#include <sstream>
#include <vector>
#include "../WAssert.h"
#include "WDendrogram.h"
WDendrogram::WDendrogram( unsigned int numElements )
: m_tree( numElements, Node() )
WDendrogram::WDendrogram( size_t n )
: m_heights( n - 1, 0.0 )
{
m_parents.reserve( 2 * n - 1 );
m_parents.resize( n, 0 );
}
WDendrogram::~WDendrogram()
size_t WDendrogram::merge( size_t i, size_t j, double height )
{
#ifdef DEBUG
std::stringstream ss;
ss << "Bug: n=" << m_heights.size() << " many leafs can lead maximal to 2n-1 many nodes in a tree but this was violated now!" << std::endl;
WAssert( m_parents.size() < 2 * m_heights.size() + 1, ss.str() );
#endif
m_parents.push_back( m_parents.size() ); // the root s always self referencing
#ifdef DEBUG
m_heights.at( m_parents.size() - 2 - m_heights.size() ) = height;
m_parents.at( i ) = m_parents.size() - 1;
m_parents.at( j ) = m_parents.size() - 1;
#else
m_heights[ m_parents.size() - 2 - m_heights.size() ] = height;
m_parents[ i ] = m_parents.back();
m_parents[ j ] = m_parents.back();
#endif
return m_parents.size() - 1;
}
WDendrogram::Node::Node()
std::string WDendrogram::toTXTString() const
{
parentTreeIdx = 0;
minTreeIdx = 0;
maxTreeIdx = 0;
dataIdx = 0;
height = 0.0;
}
std::stringstream ss;
std::map< size_t, std::set< size_t > > childsOfInnerNodes;
std::map< size_t, std::set< size_t > > preds;
std::vector< size_t > level( 2 * m_heights.size() + 1, 0 );
// first write out all fibers
for( size_t i = 0; i < m_heights.size() + 1; ++i )
{
ss << "(0, (" << i << ",))" << std::endl;
childsOfInnerNodes[ m_parents[ i ] ].insert( i );
preds[ m_parents[ i ] ] = childsOfInnerNodes[ m_parents[ i ] ];
}
for( size_t i = m_heights.size() + 1; i < 2 * m_heights.size() + 1; ++i )
{
WAssert( preds[ i ].size() == 2, "There are more or less than 2 predecessors for an inner node" );
size_t left = *( preds[ i ].begin() );
size_t right = *( preds[ i ].rbegin() );
level[ i ] = std::max( level[ left ], level[ right ] ) + 1;
preds[ m_parents[ i ] ].insert( i );
std::set< size_t > join;
std::set_union( childsOfInnerNodes[ m_parents[ i ] ].begin(),
childsOfInnerNodes[ m_parents[ i ] ].end(),
childsOfInnerNodes[ i ].begin(),
childsOfInnerNodes[ i ].end(),
std::inserter( join, join.begin() ) );
childsOfInnerNodes[ m_parents[ i ] ] = join;
ss << "(" << level[i] << ", (";
size_t numElements = childsOfInnerNodes[i].size();
for( std::set< size_t >::const_iterator cit = childsOfInnerNodes[i].begin(); cit != childsOfInnerNodes[i].end(); ++cit )
{
if( numElements == 1 )
{
ss << *cit << "), ";
}
else
{
ss << *cit << ", ";
}
numElements -= 1;
}
ss << " (" << left << ", " << right << "), " << m_heights[ i - m_heights.size() + 1 ] << ")" << std::endl;
// TODO(math): the needs to be made with a writer instead
std::ofstream file( "/home/math/pansen.txt" );
file << ss.str();
file.close();
}
return ss.str();
}
......@@ -26,91 +26,76 @@
#define WDENDROGRAM_H
#include <vector>
#include <string>
#include <boost/shared_ptr.hpp>
/**
* Hirachical binary tree datastructure with spatial layout information. Since
* join points in a dendrogram do normally not intersect a special index is
* needed. Additionally a parameter for each node and leaf, its height, is
* available.
* Hirachical binary tree datastructure with spatial layout information called dendrogram.
*
* The following description is taken from: http://en.wikipedia.org/wiki/Dendrogram A dendrogram (from Greek
* dendron "tree", -gramma "drawing") is a tree diagram frequently used to illustrate the arrangement of
* clusters produced by hierarchical clustering. Please note that each level has its height.
*
* Each leaf and inner node will obtain a new index called TreeIndex, so the
* hirachy will not overlap or intersect. As a leaf already has an index we
* call this index the DataIndex. So a leaf with DataIndex 5 is the fifth data
* element in the dataset of which this dendrogram is used for. Where as a leaf
* with TreeIndex 5 is the fifth leaf from left.
\verbatim
|
,------'--. --- 4th level
| |
|```````| | --- 3rd level
| | |
| | ...'... --- 2nd level
| | | |
|''''''''| | | | --- 1st level
| | | | |
| | | | |
o o o o o --- 0 level
\endverbatim
*
* In order to use this class for your objects ensure that the objects are labeled from <dfn>0,...,n-1</dfn>.
*/
class WDendrogram
{
friend class WDendrogramTest;
public:
/**
* Creates a new Dendrogram with unjoined elements aka leafs.
*
* \param numElements The number of unjoined or initial elements
* Constructs a new dendrogram for \c n many objects.
*
* TODO(math): Unsigned int is used to save memory here, but can't we use
* size_t (8bytes) => ask christian..
* \param n The number of leafs.
*/
explicit WDendrogram( unsigned int numElements );
explicit WDendrogram( size_t n );
/**
* Destructs a Dendrogram.
* Merges two elements (either inner nodes or leafs) given via the indices \e i and \e j.
*
* \param i The index referring either to an inner node or to a leaf.
* \param j The other index of a leaf or inner node.
* \param height The height at which those to elements join.
*
* \return The number of the inner node now representing now the parent of \e i and \e j.
*/
virtual ~WDendrogram();
size_t merge( size_t i, size_t j, double height );
protected:
/**
* Representing a node inside of the Dendrogram.
* Transform this dendrogram into a string, where each leaf or inner node is mapped to a special string.
* <dfn>"(level, (all leafs incorporated by this node), (the two direct predecessors), height if available )"</dfn>
*
* \note Be aware of the different kinds of indices used in here. See
* Description of the WDendrogram class for more details on TreeIndices and
* DataIndices.
* \return The special string as constructed from the scheme above.
*/
struct Node
{
/**
* Default constructor for a new node. So all members are an valid
* initial value: zero.
*/
Node();
/**
* The TreeIndex of the parent it belongs to.
*/
unsigned int parentTreeIdx;
std::string toTXTString() const;
/**
* All leafs grouped by this node have an bigger or equal TreeIndex
* then this \e minTreeIdx. In other words: The leftmost leaf of the
* subtree with this node as root has this TreeIndex.
*/
unsigned int minTreeIdx;
/**
* All leafs grouped by this node have an lower or equal TreeIndex then
* this \e maxTreeIdx. In other words: The rightmost leaf of the
* subtree with this node as root has this TreeIndex.
*/
unsigned int maxTreeIdx;
/**
* This is used to have a reference to the data element this node
* represents. For inner nodes clearly none exists, but for leafs this
* is the number inside of the dataset.
*/
unsigned int dataIdx;
/**
* The height of each node. Leafs have an default height of zero.
*/
double height;
};
protected:
private:
/**
* Save the whole dendrogram and keep track of the link from leafs to the
* dataset, as well as information of parents and leafs for each node.
* Stores the parents of leafs as well as of inner nodes. The first half of the arrary corresponds to the
* parents of the leafs and the second of the inner nodes. The last inner node is the top of the
* dendrogram.
*/
std::vector< size_t > m_parents;
/**
* Stores only for the inner nodes their heights.
*/
std::vector< Node > m_tree;
std::vector< double > m_heights;
};
#endif // WDENDROGRAM_H
......@@ -40,15 +40,6 @@ public:
*/
void testNewNodesHaveAlwaysZerosAssignedInitially( void )
{
WDendrogram d( 5 );
for( int i = 0; i < 5; ++i )
{
TS_ASSERT_EQUALS( d.m_tree[i].parentTreeIdx, 0 );
TS_ASSERT_EQUALS( d.m_tree[i].minTreeIdx, 0 );
TS_ASSERT_EQUALS( d.m_tree[i].maxTreeIdx, 0 );
TS_ASSERT_EQUALS( d.m_tree[i].dataIdx, 0 );
TS_ASSERT_EQUALS( d.m_tree[i].height, 0.0 );
}
}
};
......
......@@ -386,6 +386,22 @@ wmath::WVector3D WGridRegular3D::worldCoordToTexCoord( wmath::WPosition point )
r[1] += 0.5 / m_nbPosY;
r[2] += 0.5 / m_nbPosZ;
return r;
}
wmath::WPosition WGridRegular3D::texCoordToWorldCoord( wmath::WVector3D coords )
{
wmath::WVector3D r( wmath::transformPosition3DWithMatrix4D( m_matrix, coords ) );
// Correct the coordinates to have the position at the center of the texture voxel.
r[0] -= 0.5 / m_nbPosX;
r[1] -= 0.5 / m_nbPosY;
r[2] -= 0.5 / m_nbPosZ;
// Scale to [0,max]
r[0] = r[0] * m_nbPosX;
r[1] = r[1] * m_nbPosY;
r[2] = r[2] * m_nbPosZ;
return r;
}
......
......@@ -250,10 +250,16 @@ public:
/**
* Transforms world coordinates to texture coordinates.
* \param point The point with these coordinated will be transformed.
* \param point The point with these coordinates will be transformed.
*/
wmath::WVector3D worldCoordToTexCoord( wmath::WPosition point );
/**
* Transforms texture coordinates to world coordinates.
* \param coords The point with these coordinates will be transformed.
*/
wmath::WPosition texCoordToWorldCoord( wmath::WVector3D coords );
/**
* Returns the i'th voxel where the given position belongs too.
*
......
//---------------------------------------------------------------------------
//
// 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/>.
//
//---------------------------------------------------------------------------
#include <vector>
#include <boost/shared_ptr.hpp>
#include "../common/math/WPosition.h"
#include "WTractAdapter.h"
WTractAdapter::WTractAdapter( boost::shared_ptr< const std::vector< float > > pointComponents, size_t startIndex, size_t numPoints )
: m_pointComponents( pointComponents ),
m_numPoints( numPoints ),
m_startIndex( startIndex )
{
}
wmath::WPosition WTractAdapter::operator[]( size_t index ) const
{
#ifdef DEBUG
assert( m_pointComponents && "Invalid point component array inside of WTractAdapter." );
return wmath::WPosition( m_pointComponents->at( m_startIndex + index * 3 ),
m_pointComponents->at( m_startIndex + index * 3 + 1 ),
m_pointComponents->at( m_startIndex + index * 3 + 2 ) );
#else
return wmath::WPosition( ( *m_pointComponents )[ m_startIndex + index * 3],
( *m_pointComponents )[ m_startIndex + index * 3 + 1],
( *m_pointComponents )[ m_startIndex + index * 3 + 2] );
#endif
}
//---------------------------------------------------------------------------
//
// 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 WTRACTADAPTER_H
#define WTRACTADAPTER_H
#include <vector>
#include <boost/shared_ptr.hpp>
namespace wmath
{
class WVector3D;
typedef WVector3D WPosition;
}
/**
* Adapter
*/
class WTractAdapter
{
public:
/**
* Constructs a new WTract which has \ref numPoints points and a startIndex inside of the
* given components array.
*
* \param pointComponents Array where the components of the tract points are inside of
* \param startIndex The position inside of the components array of the first x coordinate.
* \param numPoints How many points this tract has
*/
WTractAdapter( boost::shared_ptr< const std::vector< float > > pointComponents, size_t startIndex, size_t numPoints );
/**
* How many positions this tract incorporates.
*/
size_t numPoints() const;
/**
* Constructs and returns a \ref wmath::WPosition out of the i'th position of this tract.
*
* \param index The index of the position of this tract. It may start at \c 0 and is always
* smaller than \ref numPoints().
*
* \return The i'th position of this tract as \ref wmath::WPosition.
*/
wmath::WPosition operator[]( size_t index ) const;
// void reset( boost::shared_ptr< const WTractData > tracts, size_t startIndex, size_t numPoints )
protected:
private:
/**
* The array where the components of this tracts live. But you will need the starting position
* and the length of the tract to access them.
*/
boost::shared_ptr< const std::vector< float > > m_pointComponents;
/**
* How many \e points aka WPositions this tract consists of.
*/
size_t m_numPoints;
/**
* The index of the x-component of the first point of this tract inside the \ref m_pointComponents array.
*/
size_t m_startIndex;
};
inline size_t WTractAdapter::numPoints() const
{
return m_numPoints;
}
#endif // WTRACTADAPTER_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/>.
//
//---------------------------------------------------------------------------
#include <vector>
#include <boost/shared_ptr.hpp>
#include "WTractData.h"
WTractData::WTractData( boost::shared_ptr< std::vector< float > > pointComponents, boost::shared_ptr< std::vector< size_t > > startIndices )
: m_pointComponents( pointComponents ),
m_startIndices( startIndices )
{
}
//---------------------------------------------------------------------------
//
// 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 WTRACTDATA_H
#define WTRACTDATA_H
#include <vector>
#include <boost/shared_ptr.hpp>
/**
* Stores the data of deterministic fiber tractograms. Derived or optional data as tangents, FA,
* etc. are not saved in here, and never will be! Just the polylines.
*/
class WTractData
{
public:
/**
* Constructs a new WTractData.
* \param pointComponents x, y, and z components of each position of each tract
* \param startIndices For each tract the index of the first x component in pointComponents.
*/
WTractData( boost::shared_ptr< std::vector< float > > pointComponents, boost::shared_ptr< std::vector< size_t > > startIndices );
/**
* \return Number of tracts.
*/
size_t numTracts() const;
protected:
private:
/**
* Stores the all components of all vertices of all tracts. First x, y and finally z component
* are arranged in this manner: \f$[x_0, y_0, z_0, ..., x_{m_0}, y_{m_0}, z_{m_0}, ... , ..., x_{m_k},
* y_{m_k}, z_{m_k}]\f$ where there are \f$k\f$ many tracts where the i'th tract has \f$m_i\f$
* vertices, but \f$3m_i\f$ compontents. In other words: m_points.size() / 3 == number of
* vertices.
*
* \note the reason for beeing restricted to float is, that graphic boards and also the tracking
* algorithms which produce those tracks are just using floats.
*/
boost::shared_ptr< std::vector< float > > m_pointComponents;
/**
* Stores for every tract the index number where it starts in the \ref m_pointComponents array.
* This means the index of each tracts first component \f$x_0\f$.
*
* \note the reason for using \c size_t instead of \c unsigned \c int is that more tracts with
* more points are in sight.
*/
boost::shared_ptr< std::vector< size_t > > m_startIndices;
};
inline size_t WTractData::numTracts() const
{
if( m_startIndices )
{
return m_startIndices->size();
}
return 0;
}
#endif // WTRACTDATA_H
......@@ -184,9 +184,11 @@ void WMainWindow::setupGUI()
this->addAction( viewMenu->addAction( "Posterior", this, SLOT( setPresetViewPosterior() ), QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_P ) ) );
QMenu* helpMenu = m_menuBar->addMenu( "Help" );
helpMenu->addAction( m_iconManager.getIcon( "help" ), "About OpenWalnut", this, SLOT( openAboutDialog() ),
QKeySequence( QKeySequence::HelpContents )
);
helpMenu->addAction( m_iconManager.getIcon( "help" ), "OpenWalnut Introduction", this, SLOT( openIntroductionDialog() ),
QKeySequence( QKeySequence::HelpContents ) );
helpMenu->addSeparator();
helpMenu->addAction( m_iconManager.getIcon( "logo" ), "About OpenWalnut", this, SLOT( openAboutDialog() ) );
helpMenu->addAction( "About Qt", this, SLOT( openAboutQtDialog() ) );
setMenuBar( m_menuBar );
......@@ -717,6 +719,10 @@ void WMainWindow::openLoadDialog()
m_loadButton->setDown( false );
}
void WMainWindow::openAboutQtDialog()
{
QMessageBox::aboutQt( this, "About Qt" );
}
void WMainWindow::openAboutDialog()
{
QMessageBox::about( this, "About OpenWalnut",
......@@ -732,6 +738,39 @@ void WMainWindow::openAboutDialog()
"Thank you for using OpenWalnut." );
}
void WMainWindow::openIntroductionDialog()
{
QMessageBox::information( this, "OpenWalnut Introduction",
"<h3>Navigation in Main View</h3>"
"<table>"