66 #include "core/common/WStringUtils.h"
67 #include "core/common/exceptions/WFileOpenFailed.h"
68 #include "core/common/WLogger.h"
82 WHtree::WHtree( std::string treeName, HC_GRID datasetGridInit,
WHcoord datasetSizeInit,
size_t numStreamlinesInit,
float logFactorInit,
83 std::vector< WHnode > leavesInit, std::vector< WHnode > nodesInit, std::vector< size_t > trackidInit,
84 std::vector< WHcoord > coordInit, std::list< WHcoord > discardInit,
float cpccInit )
85 : m_loadStatus( false ),
86 m_datasetSize( datasetSizeInit ),
87 m_datasetGrid( datasetGridInit ),
88 m_numStreamlines( numStreamlinesInit ),
89 m_logFactor( logFactorInit ),
91 m_treeName( treeName ),
92 m_leaves( leavesInit ),
94 m_coordinates( coordInit ),
95 m_trackids( trackidInit ),
96 m_discarded( discardInit )
105 : m_loadStatus( object.m_loadStatus ),
106 m_datasetSize( object.m_datasetSize ),
107 m_datasetGrid( object.m_datasetGrid ),
108 m_numStreamlines( object.m_numStreamlines ),
109 m_logFactor( object.m_logFactor ),
110 m_cpcc( object.m_cpcc ),
111 m_treeName( object.m_treeName ),
112 m_leaves( object.m_leaves ),
113 m_nodes( object.m_nodes ),
114 m_coordinates( object.m_coordinates ),
115 m_trackids( object.m_trackids ),
116 m_discarded( object.m_discarded ),
117 m_containedLeaves( object.m_containedLeaves )
136 return "tree not loaded";
148 return reportMessage;
156 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): only 0-1 leaf / no nodes";
161 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): leaves(" <<
m_leaves.size() <<
") and coordinates(" \
167 wlog::error(
"WHtree" ) <<
"WARNING @ WHtree::writeTree(): trackids(" <<
m_trackids.size() <<
") and coordinates(" \
168 <<
m_coordinates.size() <<
") vector sizes do not match. track ids will be invalid";
172 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): same number of nodes as leaves";
176 std::vector<size_t> sumLeafParents(
m_leaves.size(), 0 );
177 std::vector<size_t> sumNodeParents(
m_nodes.size(), 0 );
178 std::vector<size_t> sumNodeKids(
m_nodes.size(), 0 );
181 for( std::vector<WHnode>::const_iterator leafIter(
m_leaves.begin() ); leafIter !=
m_leaves.end(); ++leafIter )
183 nodeID_t parentID( leafIter->getParent() );
184 if( !parentID.first )
186 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): leaf has a leaf as parent";
190 if( find( kids.begin(), kids.end(), leafIter->getFullID() ) == kids.end() )
192 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): leaf parent doesnt have leaf ID among its children";
195 if( leafIter->getSize() != 1 )
197 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): leaf has a size other than 1";
200 if( leafIter->getHLevel() != 0 )
202 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): leaf has hLevel other than 0";
205 ++sumNodeKids[parentID.second];
209 for( std::vector<WHnode>::const_iterator nodeIter(
m_nodes.begin() ); nodeIter !=
m_nodes.end(); ++nodeIter )
211 std::vector<nodeID_t> kids = nodeIter->getChildren();
212 size_t currentHLevel( 0 ), currentSize( 0 );
214 for( std::vector<nodeID_t>::const_iterator kidIter( kids.begin() ); kidIter != kids.end(); ++kidIter )
216 currentHLevel = std::max( currentHLevel,
getNode( *kidIter ).
getHLevel()+1 );
219 if( kidParent != nodeIter->getFullID() )
221 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): node child (" << kidIter->first <<
"-" << kidIter->second
222 <<
") doesnt have node ID (" << nodeIter->isNode() <<
"-" << nodeIter->getID()
223 <<
") as its parent but instead has (" << kidParent.first <<
"-" << kidParent.second <<
")";
228 ++sumNodeParents[kidIter->second];
232 ++sumLeafParents[kidIter->second];
236 nodeID_t parentID( nodeIter->getParent() );
237 if( ( !parentID.first ) && ( ( nodeIter+1 ) !=
m_nodes.end() ) )
239 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): node has a leaf as parent";
242 if( ( !nodeIter->isRoot() ) && ( ( nodeIter+1 ) ==
m_nodes.end() ) )
244 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): last node does not have 0-0 as parent";
247 if( !nodeIter->isRoot() )
250 if( find( kids.begin(), kids.end(), nodeIter->getFullID() ) == kids.end() )
252 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): node parent doesnt have node ID among its children";
255 ++sumNodeKids[parentID.second];
257 if( nodeIter->getSize() != currentSize )
259 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): node " << nodeIter->getID() <<
" size (" << nodeIter->getSize()
260 <<
") is not sum of its children sizes (" << currentSize <<
")";
263 if( nodeIter->getHLevel() != currentHLevel )
265 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): node hLevel is not one more than its highest child";
271 for( std::vector<size_t>::const_iterator iter( sumLeafParents.begin() ); iter != sumLeafParents.end(); ++iter )
275 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): more than one node has the same leaf as child";
279 for( std::vector<size_t>::const_iterator iter( sumNodeParents.begin() ); iter != sumNodeParents.end()-1; ++iter )
283 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): more than one node has the same node as child";
287 if( sumNodeParents.back() != 0 )
289 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::check(): at least one node has the root node as child";
292 for( std::vector<WHnode>::const_iterator nodeIter(
m_nodes.begin() ); nodeIter !=
m_nodes.end(); ++nodeIter )
294 std::vector<nodeID_t> kids = nodeIter->getChildren();
295 if( kids.size() != sumNodeKids[nodeIter->getID()] )
298 <<
"ERROR @ WHtree::check(): node children vector size does not match the number of nodes/leafs that have it as parent" << std::endl
299 << nodeIter->printAllData();
311 return getNode( thisNode.second );
315 return getLeaf( thisNode.second );
320 if( thisNode >=
m_nodes.size() )
322 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::getNode: index is out of boundaries(" << thisNode <<
". total nodes: "
323 <<
m_nodes.size() <<
"), returning first node";
337 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::getLeaf: index is out of boundaries (" << thisLeaf <<
". total leaves: "
338 <<
m_leaves.size() <<
"), returning first leaf";
359 throw std::runtime_error(
"ERROR @ WHtree::getLeafID(): coordinate is not in the tree" );
371 throw std::runtime_error(
"ERROR @ WHtree::getTrackID(): leafID is out of boundaries" );
382 std::vector<size_t> returnVector;
386 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::getLeaves4node(): nodeID is out of boundaries";
397 std::list<size_t> worklist;
398 worklist.push_back( nodeID );
399 while( !worklist.empty() )
401 size_t currentNode( worklist.front() );
402 worklist.pop_front();
403 std::vector<nodeID_t> kids(
getNode( currentNode ).getChildren() );
404 for( std::vector<nodeID_t>::const_iterator iter( kids.begin() ); iter != kids.end(); ++iter )
408 worklist.push_back( iter->second );
412 returnVector.push_back( iter->second );
416 std::sort( returnVector.begin(), returnVector.end() );
429 return std::vector<size_t>( 1, nodeID.second );
436 std::vector<size_t> returnVector;
439 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::getBranchNodes(): nodeID is out of boundaries";
444 std::list<size_t> worklist;
445 worklist.push_back( nodeID );
446 while( !worklist.empty() )
448 size_t currentNode( worklist.front() );
449 worklist.pop_front();
450 returnVector.push_back( currentNode );
451 std::vector<nodeID_t> kids(
getNode( currentNode ).getChildren() );
452 for( std::vector<nodeID_t>::const_iterator iter( kids.begin() ); iter != kids.end(); ++iter )
456 worklist.push_back( iter->second );
460 std::sort( returnVector.begin(), returnVector.end() );
470 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::coordinate4leaf(): leafID is out of boundaries";
482 std::vector<WHcoord> returnVector;
485 for( std::vector<size_t>::const_iterator iter( containedLeaves.begin() ); iter != containedLeaves.end(); ++iter )
509 size_t sumX( 0 ), sumY( 0 ), sumZ( 0 );
510 for( std::vector<WHcoord>::const_iterator coordIter( bnCoords.begin() ); coordIter != bnCoords.end(); ++coordIter )
512 sumX += coordIter->m_x;
513 sumY += coordIter->m_y;
514 sumZ += coordIter->m_z;
516 baseCoord.
m_x = sumX/bnCoords.size();
517 baseCoord.
m_y = sumY/bnCoords.size();
518 baseCoord.
m_z = sumZ/bnCoords.size();
537 if( nodeID1 == nodeID2 )
543 size_t tempID1(
getNode( nodeID1 ).getID() ), tempID2(
getNode( nodeID2 ).getID() );
544 while( tempID1 != tempID2 )
546 if( tempID1 < tempID2 )
560 if( nodeID1 == nodeID2 )
573 node1 = ( nodeID1.second );
582 node2 = ( nodeID2.second );
591 std::vector<nodeID_t> returnVector;
592 if( ( nodeID.first ) && ( nodeID.second >=
m_nodes.size() ) )
594 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::route2Root(): leafID is out of boundaries";
600 returnVector.push_back( nodeID );
602 while( !current->
isRoot() )
605 returnVector.push_back( current->
getFullID() );
620 if( ancestorAB == ancestorAC )
622 if( ancestorAB == ancestorBC )
631 else if( ancestorAB == ancestorBC )
646 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::getBaseNodes(): branch root ID is out of boundaries (ID: "
648 return std::vector<size_t> ();
651 std::list<size_t> baseList;
652 for( std::vector<WHnode>::const_iterator leafIter(
m_leaves.begin() ); leafIter !=
m_leaves.end(); ++leafIter )
654 baseList.push_back( ( leafIter->getParent() ).second );
659 std::vector<size_t> returnVector;
661 if( root !=
getRoot().getID() )
663 for( std::list<size_t>::iterator listIter( baseList.begin() ); listIter != baseList.end(); ++listIter )
666 while( !current->
isRoot() )
668 if( current->
getID() ==root )
679 for( std::list<size_t>::const_iterator baseIter( baseList.begin() ); baseIter != baseList.end(); ++baseIter )
681 returnVector.push_back( *baseIter );
688 std::vector<nodeID_t> returnVector;
692 return std::vector<nodeID_t>();
696 std::vector<size_t> bases(
getBaseNodes( root.second ) );
697 for(
size_t i = 0; i < bases.size(); ++i )
699 returnVector.push_back( std::make_pair(
true, bases[i] ) );
719 for(
size_t i = 0; i < bases.size(); ++i )
721 if(
getNode( bases[i] ).getHLevel() > 1 )
742 nodeID_t nodeID1( std::make_pair(
false,
getLeafID( coord1 ) ) );
743 nodeID_t nodeID2( std::make_pair(
false,
getLeafID( coord2 ) ) );
750 nodeID_t ancestor(
getCommonAncestor( std::make_pair(
false, leafID1 ), std::make_pair(
false, leafID2 ) ) );
757 std::vector<size_t> &nodeVectorRef( *nodeVector );
758 for(
size_t i = 0; i < nodeVectorRef.size(); ++i )
762 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::sortBySize(): indices out of bounds (" << nodeVectorRef[i]
767 std::sort( nodeVectorRef.begin(), nodeVectorRef.end(),
compSize(
this ) );
772 std::list<size_t> &nodeListRef( *nodeList );
773 for( std::list<size_t>::const_iterator iter = nodeListRef.begin(); iter != nodeListRef.end(); ++iter )
777 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::sortBySize(): indices out of bounds (" << *iter <<
". total nodes: " <<
getNumNodes() <<
")";
781 nodeListRef.sort(
compSize(
this ) );
786 std::vector<nodeID_t> &nodeVectorRef( *nodeVector );
787 for(
size_t i = 0; i < nodeVectorRef.size(); ++i )
789 if( ( nodeVectorRef[i].first && nodeVectorRef[i].second >=
getNumNodes() ) ||
790 ( !nodeVectorRef[i].first && nodeVectorRef[i].second >=
getNumLeaves() ) )
792 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::sortBySize(): indices out of bounds(" << nodeVectorRef[ i ].first <<
"-"
793 << nodeVectorRef[ i ].second <<
". total leaves: " <<
getNumLeaves() <<
". total nodes: " <<
getNumNodes() <<
")";
797 std::sort( nodeVectorRef.begin(), nodeVectorRef.end(),
compSize(
this ) );
802 std::list<nodeID_t> &nodeListRef( *nodeList );
803 for( std::list<nodeID_t>::const_iterator iter = nodeListRef.begin(); iter != nodeListRef.end(); ++iter )
805 if( ( iter->first && iter->second >=
getNumNodes() ) ||
808 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::sortBySize(): indices out of bounds(" << iter->first <<
"-" << iter->second
813 nodeListRef.sort(
compSize(
this ) );
819 std::sort( nodeVector->begin(), nodeVector->end(),
compHLevel(
this ) );
824 std::sort( nodeVector->begin(), nodeVector->end(),
compHLevel(
this ) );
840 std::vector<size_t> emptyVect;
843 for( std::vector<WHnode>::const_iterator leafIter(
m_leaves.begin() ); leafIter !=
m_leaves.end(); ++leafIter )
845 nodeID_t thisParent( leafIter->getParent() );
848 for( std::vector<WHnode>::const_iterator nodeIter(
m_nodes.begin() ); nodeIter !=
m_nodes.end(); ++nodeIter )
851 if( !nodeIter->isRoot() )
862 std::vector<std::vector<size_t> > emptyThing;
905 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::convert2grid(): coordinate grid not recognized";
922 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): Parser error";
926 std::vector<std::string> lines = parser.
getRawLines();
927 if( lines.size() == 0 )
929 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): File is empty";
935 if( datasetStrings.size() == 0 )
937 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): Dataset size was not found in tree file";
940 if( datasetStrings.size() > 1 )
942 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): Dataset attribute had multiple lines";
945 WHcoord datasetSize( string_utils::fromString<coord_t>( datasetStrings[0][0] ),
946 string_utils::fromString<coord_t>( datasetStrings[0][1] ),
947 string_utils::fromString<coord_t>( datasetStrings[0][2] ) );
948 std::string gridString( datasetStrings[0][3] );
949 if( gridString == getGridString( HC_VISTA ) )
953 else if( gridString == getGridString( HC_NIFTI ) )
959 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): Dataset grid type string \"" << gridString <<
"\" could not be identified";
967 if( streamNumberStrings.size() == 0 )
969 wlog::error(
"WHtree" ) <<
"WARNING @ WHtree::readTree(): tracking streams number was not found in tree file,"
970 <<
" assuming streams=0 for compatibility";
973 if( streamNumberStrings.size() > 1 )
975 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): tracking streams number attribute has multiple lines";
978 if( streamNumberStrings[0].size() > 1 )
980 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): tracking streams number attribute has multiple elements";
983 m_numStreamlines = string_utils::fromString< size_t >( streamNumberStrings[0][0] );
988 if( logFactorStrings.size() == 0 )
990 wlog::error(
"WHtree" ) <<
"WARNING @ WHtree::readTree(): logarithmic normalization factor was not found in tree file,"
991 <<
" assuming logFactor=0 for compatibility";
994 if( logFactorStrings.size() > 1 )
996 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree():"
997 <<
"logarithmic normalization factor attribute has multiple lines";
1000 if( logFactorStrings[0].size() > 1 )
1002 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): logarithmic normalization factor attribute has multiple elements";
1005 m_logFactor = string_utils::fromString< float >( logFactorStrings[0][0] );
1009 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): tracking streams number ("
1019 m_leaves.reserve( coordStrings.size() );
1020 size_t leafCount( 0 );
1021 for(
size_t i = 0; i < coordStrings.size(); ++i )
1023 WHcoord tempCoord( string_utils::fromString<coord_t>( coordStrings[i][0] ),
1024 string_utils::fromString<coord_t>( coordStrings[i][1] ),
1025 string_utils::fromString<coord_t>( coordStrings[i][2] ) );
1026 WHnode tempNode( std::make_pair( 0, leafCount ) );
1034 if( indexStrings.empty() )
1038 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): no tract ids in roi file, necessary to work on nifti mode";
1053 for(
size_t i = 0; i < indexStrings.size(); ++i )
1055 size_t tempIndex( string_utils::fromString< size_t >( indexStrings[i][0] ) );
1062 m_nodes.reserve( clusterStrings.size() );
1063 size_t nodeCount( 0 );
1064 for(
size_t i = 0; i < clusterStrings.size(); ++i )
1066 dist_t distance( string_utils::fromString< dist_t > ( clusterStrings[i][0] ) );
1067 std::vector<nodeID_t>joiningNodes;
1068 for(
size_t j = 1; j < clusterStrings[i].size(); j += 2 )
1070 joiningNodes.push_back( std::make_pair( string_utils::fromString<bool>( clusterStrings[i][j] ),
1071 string_utils::fromString<size_t>( clusterStrings[i][j+1] ) ) );
1074 size_t tempSize( 0 ), tempHLevel( 0 );
1075 nodeID_t tempID( std::make_pair( 1, nodeCount ) );
1076 for( std::vector<nodeID_t>::const_iterator iter( joiningNodes.begin() ); iter != joiningNodes.end(); ++iter )
1081 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): kid id (" << iter->first <<
"-" << iter->second
1082 <<
") was out of boundaries. Nodes: " <<
m_nodes.size();
1086 tempHLevel = std::max( tempHLevel, kid->
getHLevel() );
1091 WHnode tempNode( tempID, joiningNodes, tempSize, distance, tempHLevel );
1093 m_nodes.push_back( tempNode );
1100 for(
size_t i = 0; i < discardedStrings.size(); ++i )
1102 WHcoord tempCoord( string_utils::fromString<coord_t>( discardedStrings[i][0] ),
1103 string_utils::fromString<coord_t>( discardedStrings[i][1] ),
1104 string_utils::fromString<coord_t>( discardedStrings[i][2] ) );
1112 if( !cpccStrings.empty() )
1114 if( cpccStrings.size() > 1 || cpccStrings[0].size() > 1 )
1116 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): multiple objects on cpcc attribute";
1119 m_cpcc = string_utils::fromString<float>( cpccStrings[0][0] );
1127 if( !partValueStrings.empty() )
1130 for(
size_t i = 0; i < partValueStrings.size(); ++i )
1132 float value( string_utils::fromString< float > ( partValueStrings[i][0] ) );
1138 if( !partitionStrings.empty() )
1141 for(
size_t i = 0; i < partitionStrings.size(); ++i )
1143 std::vector< size_t > thisPartition;
1144 thisPartition.reserve( partitionStrings[i].size() );
1145 for(
size_t j = 0; j < partitionStrings[i].size(); ++j )
1147 size_t partCluster( string_utils::fromString< size_t > ( partitionStrings[i][j] ) );
1148 thisPartition.push_back( partCluster );
1155 if( !partcolorStrings.empty() )
1158 for(
size_t i = 0; i < partcolorStrings.size(); ++i )
1160 std::vector< WHcoord > thisPartColors;
1161 thisPartColors.reserve( partcolorStrings[i].size() );
1163 for(
size_t j = 0; j < partcolorStrings[i].size(); ++j )
1165 std::string thisCoordstring( partcolorStrings[i][j] );
1166 if( thisCoordstring.size() != 11 )
1168 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): partition colors have wrong size (" << thisCoordstring.size()
1169 <<
") while it should be 11. string: " << thisCoordstring;
1174 std::string colorR( thisCoordstring.substr( 0, 3 ) );
1175 std::string colorG( thisCoordstring.substr( 4, 3 ) );
1176 std::string colorB( thisCoordstring.substr( 8, 3 ) );
1179 WHcoord thisColor( string_utils::fromString< coord_t > ( colorR ),
1180 string_utils::fromString< coord_t > ( colorG ),
1181 string_utils::fromString< coord_t > ( colorB ) );
1182 thisPartColors.push_back( thisColor );
1192 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): partition and colors dimensions dont match. Color field will be left empty";
1201 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): partition and colors dimensions dont match."
1202 <<
" Color field will be left empty";
1211 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): partition and value dimensions dont match. Fields will be left empty";
1220 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::readTree(): loaded tree is not consistent";
1224 m_treeName = boost::filesystem::path( filename ).stem().string();
1235 std::ofstream outFile( filename.c_str() );
1238 throw WFileOpenFailed(
"ERROR: unable to open out file: \"" + filename +
"." );
1243 std::string gridString;
1246 gridString = getGridString( HC_NIFTI );
1250 gridString = getGridString( HC_VISTA );
1253 outFile <<
"#imagesize" << std::endl <<
m_datasetSize <<
" " << gridString << std::endl <<
"#endimagesize" << std::endl;
1254 outFile << std::endl;
1260 outFile <<
"#streams" << std::endl <<
m_numStreamlines << std::endl <<
"#endstreams" << std::endl;
1262 outFile <<
"#logfactor" << std::endl <<
m_logFactor << std::endl <<
"#endlogfactor" << std::endl;
1264 outFile <<
"#coordinates" << std::endl;
1265 for( std::vector<WHcoord>::const_iterator coordIter(
m_coordinates.begin() ) ; coordIter !=
m_coordinates.end() ; ++coordIter )
1267 WHcoord currentCoord( *coordIter );
1282 outFile << currentCoord << std::endl;
1284 outFile <<
"#endcoordinates" << std::endl << std::endl;
1290 wlog::error(
"WHtree" ) <<
"WARNING @ WHtree::writeTree(): trackids(" <<
m_trackids.size() <<
") and coordinates("
1291 <<
m_coordinates.size() <<
") vector sizes do not match. track ids will note written to file";
1295 outFile <<
"#trackindex" << std::endl;
1297 for( std::vector<size_t>::const_iterator indexIter(
m_trackids.begin() ) ; indexIter !=
m_trackids.end() ; ++indexIter )
1299 outFile << *indexIter << std::endl;
1301 outFile <<
"#endtrackindex" << std::endl << std::endl;
1305 outFile <<
"#clusters" << std::endl;
1306 for( std::vector<WHnode>::const_iterator nodeIter(
m_nodes.begin() ) ; nodeIter !=
m_nodes.end() ; ++nodeIter )
1308 outFile << *nodeIter << std::endl;
1310 outFile <<
"#endclusters" << std::endl << std::endl;
1312 outFile <<
"#discarded" << std::endl;
1313 for( std::list<WHcoord>::const_iterator coordIter(
m_discarded.begin() ) ; coordIter !=
m_discarded.end() ; ++coordIter )
1315 WHcoord currentCoord( *coordIter );
1330 outFile << currentCoord << std::endl;
1332 outFile <<
"#enddiscarded" << std::endl;
1336 outFile << std::endl <<
"#partvalues" << std::endl;
1341 outFile <<
"#endpartvalues" << std::endl;
1343 outFile << std::endl <<
"#partitions" << std::endl;
1350 outFile << std::endl;
1352 outFile <<
"#endpartitions" << std::endl;
1356 outFile << std::endl <<
"#partcolors" << std::endl;
1362 size_t xcolor( thisColor.
m_x );
1363 size_t ycolor( thisColor.
m_y );
1364 size_t zcolor( thisColor.
m_z );
1366 outFile << boost::format(
"%03d;%03d;%03d " ) % xcolor % ycolor % zcolor;
1368 outFile << std::endl;
1370 outFile <<
"#endpartcolors" << std::endl;
1382 std::ofstream outFile( filename.c_str() );
1385 throw WFileOpenFailed(
"ERROR: unable to open out file: \"" + filename +
"." );
1395 outFile <<
"Streamlines per seed voxel: " <<
m_numStreamlines << std::endl;
1397 outFile <<
"Logarithmic normalization factor: " <<
m_logFactor << std::endl << std::endl;
1399 outFile <<
"============LEAVES============" << std::endl << std::endl;
1400 for( std::vector<WHnode>::const_iterator leafIter(
m_leaves.begin() ); leafIter !=
m_leaves.end(); ++leafIter )
1403 outFile <<
"ID: " << leafIter->getID() <<
". Track: " <<
getTrackID( leafIter->getID() );
1404 outFile <<
"Coord: " << currentCoord <<
" " << leafIter->printAllData() << std::endl;
1406 outFile << std::endl << std::endl <<
"============NODES============" << std::endl << std::endl;
1407 for( std::vector<WHnode>::const_iterator nodeIter(
m_nodes.begin() ) ; nodeIter !=
m_nodes.end() ; ++nodeIter )
1409 outFile << nodeIter->printAllData() << std::endl;
1418 std::ofstream outFile( filename.c_str() );
1421 throw WFileOpenFailed(
"ERROR: unable to open out file: \"" + filename +
"." );
1425 outFile <<
"#coordinates" << std::endl;
1426 for( std::vector<WHcoord>::const_iterator coordIter(
m_coordinates.begin() ) ; coordIter !=
m_coordinates.end() ; ++coordIter )
1428 WHcoord currentCoord( *coordIter );
1433 outFile << boost::format(
"%03d,%03d,%03d\n" ) % currentCoord.
m_x % currentCoord.
m_y % currentCoord.
m_z;
1435 outFile <<
"#endcoordinates" << std::endl << std::endl;
1437 outFile <<
"#clusters" << std::endl;
1438 for( std::vector<WHnode>::const_iterator nodeIter(
m_nodes.begin() ); nodeIter !=
m_nodes.end(); ++nodeIter )
1440 std::vector<nodeID_t> currentKids( nodeIter->getChildren() );
1441 for(
size_t i = 0; i < currentKids.size(); ++i )
1443 size_t currentID( currentKids[i].second );
1444 if( currentKids[i].first )
1448 outFile << boost::format(
"%06d" ) % currentID <<
"," << std::flush;
1452 outFile <<
"#endclusters" << std::endl << std::endl;
1459 std::ofstream outFile( filename.c_str() );
1462 throw WFileOpenFailed(
"ERROR: unable to open out file: \"" + filename +
"." );
1466 for( std::vector<WHnode>::const_iterator nodeIter(
m_nodes.begin() ) ; nodeIter !=
m_nodes.end() ; ++nodeIter )
1468 outFile << *nodeIter << std::endl;
1473 void WHtree::insertPartitions(
const std::vector<std::vector<size_t> > &selectedPartitions,
const std::vector< float > &selectedValues,
1474 const std::vector<std::vector<WHcoord> > &selectedColors )
1477 if( selectedPartitions.size() != selectedValues.size() )
1479 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::insertPartitions(): inserted partition set and partition value vector have different dimensions";
1487 if( !selectedColors.empty() )
1489 if( selectedColors.size() != selectedPartitions.size() )
1491 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::insertPartitions(): inserted partition color set and partition set have different dimensions";
1495 for(
size_t i = 0; i < selectedColors.size(); ++i )
1497 if( selectedColors[i].size() != selectedPartitions[i].size() )
1499 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::insertPartitions(): partition and colors dimensions dont match"
1500 <<
" (" << selectedPartitions[i].size() <<
"-" << selectedColors[i].size()
1501 <<
") Color field will be left empty";
1515 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::insertPartColors(): inserted partition color set and partition set have different dimensions";
1519 for(
size_t i = 0; i < selectedColors.size(); ++i )
1523 wlog::error(
"WHtree" ) <<
"ERROR @ WHtree::insertPartColors(): partition and colors dimensions dont match."
1524 <<
" Color field will be left empty";
1536 std::vector<std::vector<size_t> > empty1;
1537 std::vector< float > empty2;
1538 std::vector<std::vector<WHcoord> > empty3;
1547 std::vector<std::vector<WHcoord> > empty;
1554 std::vector< std::vector < nodeID_t > > *partitionSet,
1555 const bool excludeLeaves )
1557 if( depthLevel == 0 )
1559 return std::vector< std::vector< unsigned int > >();
1562 std::vector< std::vector < nodeID_t > > addedPartitionSet;
1563 std::vector< std::vector< unsigned int > > addedIndexTable;
1564 addedIndexTable.reserve( thisPartition.size() );
1565 addedPartitionSet.reserve( thisPartition.size() );
1567 for(
size_t i = 0; i < thisPartition.size(); ++i )
1575 std::vector<nodeID_t> branch;
1577 std::vector<nodeID_t> kids(
getNode( thisPartition[i] ).getChildren() );
1578 branch.reserve( kids.size() );
1579 for(
size_t j = 0; j < kids.size(); ++j )
1581 branch.push_back( kids[j] );
1586 std::vector < nodeID_t > newPartition( thisPartition );
1587 newPartition.erase( newPartition.begin()+i );
1588 newPartition.insert( newPartition.begin()+i, branch.begin(), branch.end() );
1590 addedPartitionSet.push_back( newPartition );
1591 addedIndexTable.push_back( std::vector<unsigned int>( 1, i ) );
1594 if( depthLevel > 1 )
1596 std::vector< std::vector < nodeID_t > > subPartitionSet;
1597 std::vector< std::vector< unsigned int > > subIndexTable(
getBranching( branch, depthLevel-1, &subPartitionSet, excludeLeaves ) );
1599 addedPartitionSet.reserve( addedPartitionSet.size() + subPartitionSet.size() );
1600 addedIndexTable.reserve( addedPartitionSet.size() + subPartitionSet.size() );
1602 if( subPartitionSet.size() != subIndexTable.size() )
1604 throw std::runtime_error(
"ERROR @ WHtree::getBranching(): dimension error on obtained vectors" );
1607 for(
size_t j = 0; j < subIndexTable.size(); ++j )
1609 std::vector < nodeID_t > newPartition( thisPartition );
1610 newPartition.erase( newPartition.begin()+i );
1611 newPartition.insert( newPartition.begin()+i, subPartitionSet[j].begin(), subPartitionSet[j].end() );
1612 addedPartitionSet.push_back( newPartition );
1614 std::vector< unsigned int > newIndexEntry( 1, i );
1615 newIndexEntry.insert( newIndexEntry.end(), subIndexTable[j].begin(), subIndexTable[j].end() );
1616 addedIndexTable.push_back( newIndexEntry );
1622 partitionSet->insert( partitionSet->end(), addedPartitionSet.begin(), addedPartitionSet.end() );
1624 return addedIndexTable;
1629 std::vector< std::vector < size_t > > *partitionSet )
1631 if( !partitionSet->empty() )
1633 throw std::runtime_error(
"ERROR @ WHtree::getBranching(): partition set wasnt empty" );
1636 std::vector<nodeID_t> partFullId;
1637 std::vector< std::vector < nodeID_t > > partitionFullIdSet;
1639 partFullId.reserve( thisPartition.size() );
1640 for(
size_t i = 0; i < thisPartition.size(); ++i )
1642 partFullId.push_back( std::make_pair(
true, thisPartition[i] ) );
1645 std::vector< std::vector< unsigned int > > indexTable(
getBranching( partFullId, depthLevel, &partitionFullIdSet,
true ) );
1647 partitionSet->reserve( partitionFullIdSet.size() );
1648 for(
size_t i = 0; i < partitionFullIdSet.size(); ++i )
1650 std::vector<size_t> thisSet;
1651 thisSet.reserve( partitionFullIdSet[i].size() );
1652 for(
size_t j = 0; j < partitionFullIdSet[i].size(); ++j )
1654 if( partitionFullIdSet[i][j].first )
1656 thisSet.push_back( partitionFullIdSet[i][j].second );
1660 wlog::error(
"WHtree" ) <<
"WARNING @ WHtree::getBranching(), leaves were returned";
1663 partitionSet->push_back( thisSet );
1675 if( thisNode >=
m_nodes.size() )
1681 return &(
m_nodes[thisNode] );
1686 if( thisNode.first )
1721 for( std::vector<WHnode>::iterator nodesIter(
m_nodes.begin() ); nodesIter !=
m_nodes.end(); ++nodesIter )
1723 nodesIter->setSize( 0 );
1724 nodesIter->setHLevel( 0 );
1727 for( std::vector<WHnode>::const_iterator leavesIter(
m_leaves.begin() ); leavesIter !=
m_leaves.end(); ++leavesIter )
1730 size_t currentSize( parentNode->
getSize() );
1731 if( !( leavesIter->isFlagged() ) )
1734 parentNode->
setSize( currentSize+1 );
1739 for( std::vector<WHnode>::iterator nodesIter(
m_nodes.begin() ); nodesIter !=
m_nodes.end()-1; ++nodesIter )
1742 size_t currentNodeSize( nodesIter->getSize() );
1743 size_t currentPapaSize( parentNode->
getSize() );
1744 parentNode->
setSize( currentPapaSize + currentNodeSize );
1745 if( currentNodeSize < 2 )
1748 nodesIter->setFlag(
true );
1749 if( currentNodeSize > 0 )
1751 parentNode->
setHLevel( nodesIter->getHLevel() );
1756 parentNode->
setHLevel( std::max( parentNode->
getHLevel(), nodesIter->getHLevel()+1 ) );
1760 for( std::vector<WHnode>::iterator nodesIter(
m_nodes.begin() ); nodesIter !=
m_nodes.end(); ++nodesIter )
1762 size_t numNewKids( 0 );
1763 std::vector<nodeID_t> kids( nodesIter->getChildren() );
1765 for( std::vector<nodeID_t>::iterator kidsIter( kids.begin() ); kidsIter != kids.end(); ++kidsIter )
1783 if( numNewKids <= 1 )
1785 nodesIter->setFlag(
true );
1792 size_t leafCounter( 0 ), nodeCounter( 0 );
1794 for(
size_t i = 0; i <
m_leaves.size(); ++i )
1798 lookupLeafID[i] = leafCounter++;
1802 for(
size_t i = 0; i <
m_nodes.size(); ++i )
1806 lookupNodeID[i] = nodeCounter++;
1810 for(
size_t i = 0; i <
m_nodes.size(); ++i )
1817 if( searchNode->
isRoot() )
1825 lookupParentID[i] = 0;
1829 lookupParentID[i] = lookupNodeID[searchNode->
getID()];
1832 if( lookupParentID[i] == INVALID )
1834 throw std::runtime_error(
"ERROR @ WHtree::cleanup(): error filling new parent ID lookup table" );
1839 lookupParentID[i] = lookupNodeID[
m_nodes[i].getID()];
1845 size_t discardedLeaves( 0 ), discardedNodes( 0 );
1846 std::vector<WHnode>::iterator leavesDelIter(
m_leaves.begin() );
1847 std::vector<WHcoord>::iterator coordDelIter(
m_coordinates.begin() );
1848 std::vector< size_t >::iterator trackidIter(
m_trackids.begin() );
1850 while( leavesDelIter !=
m_leaves.end() )
1852 if( leavesDelIter->isFlagged() )
1856 leavesDelIter =
m_leaves.erase( leavesDelIter );
1858 trackidIter =
m_trackids.erase( trackidIter );
1868 std::vector<WHnode>::iterator nodesDelIter(
m_nodes.begin() );
1869 while( nodesDelIter !=
m_nodes.end() )
1871 if( nodesDelIter->isFlagged() )
1874 nodesDelIter =
m_nodes.erase( nodesDelIter );
1884 for( std::vector<WHnode>::iterator leavesIter(
m_leaves.begin() ); leavesIter !=
m_leaves.end(); ++leavesIter )
1886 size_t newID( lookupLeafID[leavesIter->getID()] );
1887 size_t newParentID( lookupParentID[leavesIter->getParent().second] );
1889 if( ( newID == INVALID ) || ( newParentID == INVALID ) )
1891 wlog::error(
"WHtree" ) <<
"Discarded " << discardedLeaves<<
" and " << discardedNodes<<
" nodes" << std::endl
1892 <<
"Old ID: " << leavesIter->getID() <<
". New ID: " << newID<<
". Old parent ID: " << leavesIter->getParent().second
1893 <<
". New parent ID: " << newParentID;
1895 throw std::runtime_error(
"ERROR @ WHtree::cleanup(): error updating leaf IDs, invalid lookup table value" );
1898 leavesIter->setID( std::make_pair(
false, newID ) );
1899 leavesIter->setParent( std::make_pair(
true, newParentID ) );
1902 for( std::vector<WHnode>::iterator nodesIter(
m_nodes.begin() ); nodesIter !=
m_nodes.end(); ++nodesIter )
1904 size_t newID( lookupNodeID[nodesIter->getID()] );
1906 size_t newParentID( 0 );
1907 if( ( nodesIter+1 ) !=
m_nodes.end() )
1909 newParentID = ( lookupParentID[nodesIter->getParent().second] );
1912 std::vector<nodeID_t> emptyKids;
1914 if( ( newID == INVALID ) || ( newParentID == INVALID ) )
1916 throw std::runtime_error(
"ERROR @ WHtree::cleanup(): error updating node IDs, invalid lookup table value" );
1919 if( newParentID == 0 )
1921 if( ( nodesIter+1 ) !=
m_nodes.end() )
1923 wlog::error(
"WHtree" ) << std::endl <<
"Node says its root: " << nodesIter->printAllData() << std::endl
1924 <<
"New ID: " << newID <<
". New parent ID: " << newParentID << std::endl
1925 <<
"But last node is: " << (
m_nodes.end()-1 )->printAllData() << std::endl
1926 <<
"New ID: " << lookupNodeID[(
m_nodes.end()-1 )->getID()] << std::endl;
1927 throw std::runtime_error(
"ERROR @ WHtree::cleanup(): pruning failed, top of tree is not last node in vector" );
1929 nodesIter->setParent( std::make_pair(
false, 0 ) );
1933 nodesIter->setParent( std::make_pair(
true, newParentID ) );
1936 nodesIter->setID( std::make_pair(
true, newID ) );
1937 nodesIter->setChildren( emptyKids );
1938 nodesIter->setHLevel( 0 );
1942 for( std::vector<WHnode>::iterator leavesIter(
m_leaves.begin() ); leavesIter !=
m_leaves.end(); ++leavesIter )
1945 std::vector<nodeID_t> currentKids( parentNode->
getChildren() );
1946 currentKids.push_back( leavesIter->getFullID() );
1950 for( std::vector<WHnode>::iterator nodesIter(
m_nodes.begin() ); nodesIter !=
m_nodes.end(); ++nodesIter )
1952 if( nodesIter->isRoot() )
1957 std::vector<nodeID_t> currentKids( parentNode->
getChildren() );
1958 currentKids.push_back( nodesIter->getFullID() );
1960 parentNode->
setHLevel( std::max( parentNode->
getHLevel(), ( nodesIter->getHLevel() )+1 ) );
1966 throw std::runtime_error(
"ERROR @ WHtree::cleanup(): resulting tree is not consistent" );
1968 if( discardedLeaves != 0 || discardedNodes != 0 )
1974 if( outLookup != 0 )
1976 *outLookup = lookupNodeID;
1981 return std::make_pair( discardedLeaves, discardedNodes );
1989 wlog::error(
"WHtree" ) <<
"WARNING@ Debinarize: base nodes have mixed nodes and leaves, debinarize will be standard ";
1990 keepBaseNodes =
false;
1994 std::vector<bool> validNode(
getNumNodes(),
true );
1995 std::vector<std::vector<nodeID_t> > realChildren;
1997 std::vector<size_t> realParentsforLeaves(
getNumLeaves(), 0 );
1998 std::vector<size_t> realParentsforNodes(
getNumNodes(), 0 );
2001 if( !keepBaseNodes )
2006 size_t currentNode(
fetchLeaf(
id )->getParent().second );
2007 dist_t currentDist(
fetchNode( currentNode )->getDistLevel() );
2009 if(
fetchNode( currentNode )->isRoot() )
2011 realParentsforLeaves[id] = currentNode;
2012 realChildren[currentNode].push_back( std::make_pair(
false,
id ) );
2015 size_t nextParent(
fetchNode( currentNode )->getParent().second );
2016 dist_t nextDist(
fetchNode( nextParent )->getDistLevel() );
2018 while( currentDist == nextDist )
2020 validNode[currentNode] =
false;
2021 currentNode = nextParent;
2022 currentDist = nextDist;
2032 realParentsforLeaves[id] = currentNode;
2033 realChildren[currentNode].push_back( std::make_pair(
false,
id ) );
2040 size_t currentNode(
fetchLeaf(
id )->getParent().second );
2042 if(
fetchNode( currentNode )->isRoot() )
2044 realParentsforLeaves[id] = currentNode;
2045 realChildren[currentNode].push_back( std::make_pair(
false,
id ) );
2049 realParentsforLeaves[id] = currentNode;
2050 realChildren[currentNode].push_back( std::make_pair(
false,
id ) );
2055 for(
unsigned int id = 0;
id <
getNumNodes()-1; ++id )
2057 size_t currentNode(
fetchNode(
id )->getParent().second );
2058 dist_t currentDist(
fetchNode( currentNode )->getDistLevel() );
2060 if(
fetchNode( currentNode )->isRoot() )
2062 realParentsforNodes[id] = currentNode;
2065 realChildren[currentNode].push_back( std::make_pair(
true,
id ) );
2069 size_t nextParent(
fetchNode( currentNode )->getParent().second );
2070 dist_t nextDist(
fetchNode( nextParent )->getDistLevel() );
2072 while( currentDist == nextDist )
2074 validNode[currentNode] =
false;
2076 currentNode = nextParent;
2077 currentDist = nextDist;
2087 realParentsforNodes[id] = currentNode;
2089 realChildren[currentNode].push_back( std::make_pair(
true,
id ) );
2097 if( validNode[i] && ( realChildren[i].empty() ) )
2099 wlog::error(
"WHtree" ) <<
"node (1-" << i <<
") has no real children";
2100 throw std::runtime_error(
"ERROR @ WHtree::debinarize(): node has no real children" );
2105 size_t nbCount( 0 );
2106 const size_t invalid( validNode.size()+1 );
2107 std::vector<size_t> changeLookup( validNode.size(), invalid );
2108 for(
size_t i = 0; i < validNode.size(); ++i )
2112 changeLookup[i] = nbCount;
2118 for(
size_t i = 0; i < realChildren.size(); ++i )
2120 for(
size_t j = 0; j < realChildren[i].size(); ++j )
2122 if( realChildren[i][j].first )
2124 size_t newName( changeLookup[realChildren[i][j].second] );
2125 if( newName == invalid )
2127 throw std::runtime_error(
"ERROR @ WHtree::debinarize(): error renaming node children" );
2129 realChildren[i][j].second = newName;
2137 size_t realDad( changeLookup[realParentsforLeaves[
id]] );
2138 if( realDad == invalid )
2140 throw std::runtime_error(
"ERROR @ WHtree::debinarize(): error renaming nb leaf parents" );
2147 std::vector<WHnode> nbNodes;
2149 for(
unsigned int id = 0;
id <
getNumNodes()-1; ++id )
2153 size_t realDad( changeLookup[realParentsforNodes[
id]] );
2154 if( realDad == invalid )
2156 wlog::error(
"WHtree" ) <<
"node (1-" <<
id <<
") is valid but has invalid dad, ( preDad was 1-" << realParentsforNodes[ id ]
2158 throw std::runtime_error(
"ERROR @ WHtree::debinarize(): error renaming nb node parents" );
2160 WHnode thisnode( std::make_pair(
true, changeLookup[
id] ), realChildren[
id],
2162 thisnode.
setParent( std::make_pair(
true, realDad ) );
2163 nbNodes.push_back( thisnode );
2168 nbNodes.push_back( rootnode );
2177 for(
unsigned int id = 0;
id <
getNumNodes(); ++id )
2180 std::vector<nodeID_t> currentKids( currentNode->
getChildren() );
2181 size_t currentHLevel( 0 );
2182 for(
size_t j = 0; j < currentKids.size(); ++j )
2184 currentHLevel = std::max( currentHLevel,
fetchNode( currentKids[j] )->getHLevel()+1 );
2186 currentNode->
setHLevel( currentHLevel );
2191 throw std::runtime_error(
"ERROR @ WHtree::debinarize(): resutling tree is not consistent" );
2194 size_t discardedNodes( origNumNodes -
getNumNodes() );
2196 if( discardedNodes != 0 )
2202 return discardedNodes;
2208 for( std::vector<WHnode>::iterator nodesIter(
m_nodes.begin() ); nodesIter !=
m_nodes.end(); ++nodesIter )
2211 std::vector<nodeID_t> currentKids( currentNode->
getChildren() );
2213 for(
size_t j = 0; j < currentKids.size(); ++j )
2229 for( std::vector<WHnode>::reverse_iterator nodesIter(
m_nodes.rbegin() ); nodesIter !=
m_nodes.rend(); ++nodesIter )
2232 std::vector<nodeID_t> currentKids( currentNode->
getChildren() );
2234 for(
size_t j = 0; j < currentKids.size(); ++j )
2249 if( errorMult > 100 || errorMult <= 0 )
2253 double errorMargin( errorMult * 1E-5 );
2255 for( int64_t i =
m_nodes.size()-1; i >= 0; )
2258 size_t currentSize( currentNode->
getSize() );
2261 std::vector<nodeID_t> currentKids( currentNode->
getChildren() );
2263 double newLevelSum( 0 );
2264 size_t remainingSize( currentSize );
2265 bool doCorrect(
false );
2267 for(
size_t j = 0; j < currentKids.size(); ++j )
2274 remainingSize -= kid->
getSize();
2282 double correctedLevel( ( newLevelSum + ( remainingSize * currentLevel ) ) / currentSize );
2286 for(
size_t j = 0; j < currentKids.size(); ++j )
2297 if( currentNode->
isRoot() )
2306 if( correctedLevel > parentLevel + errorMargin )
2308 i = parentNode->
getID();
Thrown whenever a file could not be opened.
class implements text file loading and several convinience methods to access
std::vector< std::vector< std::string > > getLinesForTagSeparated(std::string tag)
getter
std::vector< std::string > getRawLines()
getter
bool readFile()
helper function to read a text file
this class to contain a seed voxel coordinate.
WHcoord nifti2vista(const WHcoord dataSize) const
transform coordinates to vista format
std::string getNameString() const
returns a string with the coordinates of the voxel in the form "xxx_yyy_zzz"
WHcoord vista2nifti(const WHcoord dataSize) const
transform coordinates to vista format
this class implements a hierarchical tree node with several relevant attributes
size_t getSize() const
returns number of elements contained by the node
void setParent(const nodeID_t newDad)
sets the parent id field to the specified value
bool isFlagged() const
returns true if object is flagged for pruning
void setChildren(std::vector< nodeID_t > newKids)
sets the children vector to the input values
void setHLevel(const size_t newLevel)
sets the hierarchical level field to the specified value
bool isLeaf() const
returns true if object is a leaf
size_t getHLevel() const
returns maximum number of nodes between the node and a leaf element
void setSize(const size_t newSize)
sets the size field to the specified value
bool isRoot() const
returns true if object is the root of the tree
size_t getID() const
returns node/leaf ID
dist_t getDistLevel() const
returns distance level at which the element was formed
void setDistLevel(const dist_t newLevel)
sets the distance level field to the specified value
nodeID_t getFullID() const
returns full ID
nodeID_t getParent() const
returns parent ID
std::vector< nodeID_t > getChildren() const
returns a vector with the ids of the children of that node
this class implements a hierarchical tree and provides functions for creation, partitioning,...
void loadContainedLeaves()
stores the contained leaves for each node
std::vector< size_t > getRootBaseNodes() const
returns a vector with all the nodes that have direct link to leaves from the main root
const WHnode & getRoot() const
returns a const reference to the root node
size_t getCommonAncestor(const size_t nodeID1, const size_t nodeID2) const
retrieves the the first common ancestor node of two given nodes
float m_cpcc
Stores the cpcc value of the tree.
std::vector< std::vector< WHcoord > > m_selectedColors
Stores the colors of the selected partitions.
bool writeTreeDebug(const std::string &filename) const
writes all redundant tree data for debugging purposes
std::vector< std::vector< size_t > > m_containedLeaves
Stores the contained leafs of each node.
std::vector< size_t > getBaseNodes(const size_t root) const
returns a vector with all the nodes that have direct link to leaves fro the indicated subtree
size_t getNumNodes() const
Returns the number of nodes of the tree.
dist_t getDistance(const size_t nodeID1, const size_t nodeID2) const
computes the cophenetic distance between 2 nodes
std::vector< WHcoord > m_coordinates
Stores the coordinates of the leaf voxels.
std::vector< WHcoord > getCoordinates4node(const size_t nodeID) const
Returns a vector with all the seed voxel coordinates contained in that cluster.
std::vector< size_t > getLeaves4node(const size_t nodeID) const
Returns a vector with all the leaf IDs contained in that cluster.
WHcoord m_datasetSize
Stores the size of the dataset this tree was built from.
std::vector< WHnode > m_nodes
Stores all the nodes (non-leaves) of the tree.
void insertPartitions(const std::vector< std::vector< size_t > > &selectedPartitions, const std::vector< float > &selectedValues, const std::vector< std::vector< WHcoord > > &selectedColors=std::vector< std::vector< WHcoord > >())
insert a set of partitions into the tree data
const WHnode & getNode(const nodeID_t &thisNode) const
returns a const pointer to the node indicated by the ID
size_t getLeafID(const WHcoord &thisCoord) const
returns the leaf ID of a coordinate in the tree
bool m_loadStatus
Stores all the leaves of the tree (represents a single voxel, for several purposes a leaf also counts...
void clearPartitions()
delete all data related to saved partitions
void clearPartColors()
delete only color data of the saved partitions
bool writeTreeOldWalnut(const std::string &filename) const
writes dta for working with the old walnut module
void forceMonotonicityDown()
eliminates non monotonic steps in the tree top-down, raising the level of parents involved in the non...
dist_t getLeafDistance(const size_t leafID1, const size_t leafID2) const
computes the cophenetic distance between 2 leaves
std::vector< std::vector< size_t > > m_selectedPartitions
Stores a set of selected partitions.
unsigned int getTripletOrder(const nodeID_t &nodeIDa, const nodeID_t &nodeIDb, const nodeID_t &nodeIDc) const
checks the joining order of a given triplet
size_t debinarize(const bool keepBaseNodes=false)
merges nodes joining binary at the same level into non-binary structures
const WHnode & getLeaf(const size_t thisLeaf) const
returns a const pointer to the leaf indicated by the ID
std::vector< WHnode > m_leaves
Stores all the leaves of the tree (represents a single voxel, for several purposes a leaf also counts...
bool writeTreeSimple(const std::string &filename) const
writes only join data without coordinates or reading labels
void clearContainedLeaves()
frees the memory of m_containedLeaves
WHnode * fetchNode(const nodeID_t &thisNode)
returns a pointer to the node indicated by the ID
std::string getReport(bool longMsg=true) const
writes out a small report status of the tree
std::pair< size_t, size_t > cleanup(std::vector< size_t > *outLookup=0)
cleans leaves/nodes set to be pruned
void sortByHLevel(std::vector< size_t > *const nodeVector) const
Reorders the nodes in the vector according to their hierarchical level.
size_t getTrackID(const size_t &leafID) const
returns the corresponding track ID to a leaf ID on the tree
void insertPartColors(const std::vector< std::vector< WHcoord > > &selectedColors)
insert a set of partitions colors into the tree data in case a set of saved partitions is already pre...
WHcoord getMeanCoordinate4node(const size_t nodeID) const
Returns the mean coordinate of all the seed voxel coordinates contained in that cluster.
WHnode * fetchRoot()
returns a pointer to the root node
void sortBySize(std::vector< size_t > *const nodeVector) const
Reorders the nodes in the vector according to their size.
float m_logFactor
logarithmic normalization factor used in the tractograms when building the tree
size_t m_numStreamlines
number of streamlines generated form each seed voxel in the tractograms used to build the tree
void forceMonotonicity(double errorMult=1)
eliminates non monotonic steps in the tree while keeping as much information as possible.
std::string m_treeName
Stores the name of the tree file.
bool testRootBaseNodes() const
tests if all base nodes have only leaf children
bool writeTree(const std::string &filename, const bool isNifti=true) const
writes the current tree data
std::vector< nodeID_t > getRoute2Root(const nodeID_t &nodeID) const
node route to root node
bool check() const
checks tree integrity
HC_GRID m_datasetGrid
Stores the the type of coordinate grid of the dataset.
std::vector< size_t > m_trackids
Stores the ids of the seed tracts correesponding to each leaf.
bool convert2grid(const HC_GRID newGrid)
converts all the coordinates to the grid format indicated
std::vector< size_t > getBranchNodes(const size_t nodeID) const
Returns a vector with all the node IDs contained in that branch.
WHcoord getCoordinate4leaf(const size_t leafID) const
the coordinates of a particular leaf
bool readTree(const std::string &filename)
Reads the the tree data from a file and creates the structure, containing it in the leaves,...
WHnode * fetchLeaf(const size_t thisLeaf)
returns a pointer to the leaf indicated by the ID
std::vector< float > m_selectedValues
Stores the quality values of the selected partitions.
size_t getNumLeaves() const
Returns the number of leaves of the tree.
std::list< WHcoord > m_discarded
Stores the coordinates of the voxels that were discarded during the process of building the tree.
std::vector< std::vector< unsigned int > > getBranching(const std::vector< nodeID_t > &thisPartition, size_t depthLevel, std::vector< std::vector< nodeID_t > > *partitionSet, const bool excludeLeaves)
gets all possble sets of sub-partitions in a tree given an initial partition and a depth level (where...
void forceMonotonicityUp()
eliminates non monotonic steps in the tree bottom-up, lowering the level of children involved in the ...
std::string toString(const T &value)
Convert a given value to a string.
WStreamedLogger error(const std::string &source)
Logging an error message.
implements a compare operator for nodes, depending on the hierarchical level
implements a compare operator for nodes inside a tree structure, depending on the Size