-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMergeTree.h
172 lines (129 loc) · 5.97 KB
/
MergeTree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*********************************************************************
* Author : Himangshu Saikia
* Email : [email protected]
* Project : Merge Tree Library
*
*********************************************************************
*/
#pragma once
#include "globals.h"
#include "ScalarField.h"
#include <map>
#include <set>
#include <functional>
#include <fstream>
#include <istream>
#include <string>
namespace mtlib {
typedef size_t VertexIdx;
typedef int FeatureIdx;
enum CPType { EXTREMUM, SADDLE, GBL_EXT, REGULAR };
enum SimplificationMethod { SIM_THRESHOLD, SIM_NUMBER };
enum HierarchyType { PERSISTENCE, INTEGRATED_INTENSITY_DIFFERENCE };
struct CriticalPoint {
VertexIdx idx;
CPType typ;
};
struct Branch {
size_t brReprExtIdx; // branch representative extremum index
size_t saddleIdx; // saddle index at which the branch is plucked off from
double weight; // normalized height difference of this branch with root branch being 1.0 in case persistence simplication is used
// sum of f(x) - f(s) where x is a voxel in this branch, and s is the saddle in case integrated intensity simplification is used.
size_t level;
int vol; // cumulative volume of this branch (branch volume + all child branches' volume)
};
struct ConciseSMT {
std::map<int, int> unAugIdxTree; // map {cp_i => i --> cp_j => j}, -1 is global extremum
std::vector<CriticalPoint> cps; // remaining subtrees
};
struct SimplifiedMergeTree {
std::map<FeatureIdx, FeatureIdx> unAugIdxTree; // map {cp_i => i --> cp_j => j}, -1 is global extremum
std::vector<CriticalPoint> cps; // remaining critical points
std::vector<FeatureIdx> levelSetReprIdxMap; // map {v_i -> cp_j => j}
std::vector<double> simplifiedScalarField; // All voxels of simplified edges get flattened out
std::map <FeatureIdx, std::vector<FeatureIdx> > iUnAugIdxTree; // map {cp_i => i --> child(cp_i) == <cp_j> => <j> }
FeatureIdx rootIdxTree; // root of inverted tree. Last saddle.
Dimensions dims;
SimplifiedMergeTree() {
}
~SimplifiedMergeTree() {
}
void getIsoLevelSets(std::vector<FeatureIdx>& belongsTo, FeatureIdx& maxFeatureIdx, const double isoValue);
ConciseSMT getConciseSMT() {
ConciseSMT c;
c.cps = cps;
c.unAugIdxTree = unAugIdxTree;
return c;
}
void writeUnAugTree(const std::string& filename) {
std::ofstream f;
f.open(filename);
for (const auto& e : unAugIdxTree) {
f << cps[e.first].idx << "->" << cps[e.second].idx << "\n";
}
f.close();
}
};
class MergeTree {
public:
struct doCompare
{
doCompare(const MergeTree& info) : m_info(info) { } // only if you really need the object state
const MergeTree& m_info;
bool operator()(const size_t& idx1, const size_t& idx2)
{
size_t rep_idx1 = idx1;
size_t rep_idx2 = idx2;
if (m_info.brIdxMap_.find(idx1) != m_info.brIdxMap_.end()) {
rep_idx1 = m_info.brs_[m_info.brIdxMap_.find(idx1)->second].brReprExtIdx;
}
if (m_info.brIdxMap_.find(idx2) != m_info.brIdxMap_.end()) {
rep_idx2 = m_info.brs_[m_info.brIdxMap_.find(idx2)->second].brReprExtIdx;
}
return m_info.sortedOrder_[rep_idx1] < m_info.sortedOrder_[rep_idx2];
}
};
MergeTree(ScalarField& sf, std::vector<VertexIdx>& vertexOrder, const HierarchyType& htyp);
void createTree();
void createAugTree();
static void drawUnAugTree(std::ofstream& file, const std::map<int, int>& unAugTree, const std::string& prefix);
void drawUnAugTree(std::ofstream& file, const std::string& prefix);
void writeUnAugTree(const std::string& filename);
void writeSimpMap(const std::string& filename);
void drawBDTree(std::ofstream& file, const std::string& prefix);
void writeStatistics(std::string filename);
void createSimplifiedMergeTree(double threshold, size_t numToRemain, SimplifiedMergeTree& smt, SimplificationMethod method) const;
static bool isAncestor(const int & nodeIdx, const int & ancestorIdx, const std::map<int, int>& unAugTree);
size_t getTreeSize(); // num of critical points
size_t getBDTSize(); // number of branches
std::vector<size_t> augTree_; // size = entire dataset
std::vector<CriticalPoint> cps_; // making public for testing, should be private
private:
ScalarField& sf_;
HierarchyType hierarchyType_;
std::vector<VertexIdx>& vertexOrder_; //ordered list of vertices
std::vector<VertexIdx> sortedOrder_; // vertex to position in sorted array
size_t numVoxels_;
//Union Find functions
VertexIdx rootCpIdx_; // index of global min (max) of join(split) tree
std::vector<VertexIdx> activeLevelSetReprMap_; // updates using the find function to the bottom-most CP
std::map<VertexIdx, VertexIdx> unAugTree_; // map to indicate child CP to parent CP idx in volume, size = size of CPs
//std::vector<CriticalPoint> cps_;
std::map<VertexIdx, FeatureIdx> cpIdxMap_; // map of cp's volume idx to index in 'cps' array
//Branch Decomposition
std::map<size_t, size_t> BDTree_; // map to indicate child CP to parent CP in 'brs' array, size = size of BDT
std::vector<Branch> brs_;
std::map<VertexIdx, FeatureIdx> brIdxMap_; // map of cp's volume idx to index in 'brs' array
//simplification map, based on the BDT
std::map<FeatureIdx, FeatureIdx> simpMap_; // x simplifies to simpMap_[x], so any member of x points to simpMap_[x] after x is simplified
std::vector<VertexIdx> levelSetReprMap_; // map to say which voxel belongs to which CP, size = entire dataset
size_t findComponent(const size_t& idx);
void createNewComponent(const size_t& idx, const CPType& typ);
void mergeWithOneComponent(const size_t& idx, const size_t& belongsTo);
void mergeWithManyComponents(const size_t& idx, const std::vector<size_t>& saddleOf);
//void createSimplificationOrder();
void doConsistencyCheck();
int createSimplificationOrderForPath(const int& startCpIdx, const std::map<size_t, bool>& survivedCPs, std::map<int, int>& simpMap) const;
void setSimpMap(int idx, int master);
};
}