Commit 2e0f052a4108ad47246a9b2be824b8f87fc7e1c5

Authored by Pavel Govyadinov
1 parent 6ada8448

minor changes to network

stim/biomodels/network.h
@@ -33,7 +33,10 @@ class network{ @@ -33,7 +33,10 @@ class network{
33 public: 33 public:
34 unsigned v[2]; //unique id's designating the starting and ending 34 unsigned v[2]; //unique id's designating the starting and ending
35 // default constructor 35 // default constructor
36 - edge() : cylinder<T>(){v[1] = -1; v[0] = -1;} 36 + edge() : cylinder<T>()
  37 + {
  38 + v[1] = -1; v[0] = -1;
  39 + }
37 /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor 40 /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor
38 41
39 ///@param p is an array of positions in space 42 ///@param p is an array of positions in space
@@ -54,7 +57,7 @@ class network{ @@ -54,7 +57,7 @@ class network{
54 /// Output the edge information as a string 57 /// Output the edge information as a string
55 std::string str(){ 58 std::string str(){
56 std::stringstream ss; 59 std::stringstream ss;
57 - ss<<"("<<cylinder<T>::size()<<")\tl = "<<length()<<"\t"<<v[0]<<"----"<<v[1]; 60 + ss<<"("<<cylinder<T>::size()<<")\tl = "<<this.length()<<"\t"<<v[0]<<"----"<<v[1];
58 return ss.str(); 61 return ss.str();
59 } 62 }
60 63
@@ -64,9 +67,9 @@ class network{ @@ -64,9 +67,9 @@ class network{
64 class vertex : public stim::vec3<T> 67 class vertex : public stim::vec3<T>
65 { 68 {
66 public: 69 public:
67 - //std::vector<unsigned int> edges; //indices of edges connected to this node.  
68 - std::vector<unsigned int> e[2]; //indices of edges going out (e[0]) and coming in (e[1])  
69 - //stim::vec3<T> p; //position of this node in physical space. 70 + //std::vector<unsigned int> edges; //indices of edges connected to this node.
  71 + std::vector<unsigned int> e[2]; //indices of edges going out (e[0]) and coming in (e[1])
  72 + //stim::vec3<T> p; //position of this node in physical space.
70 73
71 //constructor takes a stim::vec 74 //constructor takes a stim::vec
72 vertex(stim::vec3<T> p) : stim::vec3<T>(p){} 75 vertex(stim::vec3<T> p) : stim::vec3<T>(p){}
@@ -99,6 +102,18 @@ protected: @@ -99,6 +102,18 @@ protected:
99 102
100 public: 103 public:
101 104
  105 + ///default constructor
  106 + network()
  107 + {
  108 +
  109 + }
  110 +
  111 + ///constructor with a file to load.
  112 + network(std::string fileLocation)
  113 + {
  114 + load_obj(fileLocation);
  115 + }
  116 +
102 ///Returns the number of edges in the network. 117 ///Returns the number of edges in the network.
103 unsigned int edges(){ 118 unsigned int edges(){
104 return E.size(); 119 return E.size();
@@ -110,71 +125,74 @@ public: @@ -110,71 +125,74 @@ public:
110 } 125 }
111 126
112 stim::cylinder<T> get_cylinder(unsigned f){ 127 stim::cylinder<T> get_cylinder(unsigned f){
113 - return E[f]; //return the specified edge (casting it to a fiber) 128 + return E[f]; //return the specified edge (casting it to a fiber)
114 } 129 }
115 130
116 //load a network from an OBJ file 131 //load a network from an OBJ file
117 void load_obj(std::string filename){ 132 void load_obj(std::string filename){
118 133
119 - stim::obj<T> O; //create an OBJ object  
120 - O.load(filename); //load the OBJ file as an object 134 + stim::obj<T> O; //create an OBJ object
  135 + O.load(filename); //load the OBJ file as an object
121 136
122 - std::vector<unsigned> id2vert; //this list stores the OBJ vertex ID associated with each network vertex 137 + std::vector<unsigned> id2vert; //this list stores the OBJ vertex ID associated with each network vertex
123 138
124 - unsigned i[2]; //temporary, IDs associated with the first and last points in an OBJ line 139 + unsigned i[2]; //temporary, IDs associated with the first and last points in an OBJ line
125 140
126 //for each line in the OBJ object 141 //for each line in the OBJ object
127 for(unsigned int l = 1; l <= O.numL(); l++){ 142 for(unsigned int l = 1; l <= O.numL(); l++){
128 143
129 - std::vector< stim::vec<T> > c; //allocate an array of points for the vessel centerline 144 + std::vector< stim::vec<T> > c; //allocate an array of points for the vessel centerline
130 O.getLine(l, c); //get the fiber centerline 145 O.getLine(l, c); //get the fiber centerline
131 146
132 std::vector< stim::vec3<T> > c3(c.size()); 147 std::vector< stim::vec3<T> > c3(c.size());
133 for(size_t j = 0; j < c.size(); j++) 148 for(size_t j = 0; j < c.size(); j++)
134 c3[j] = c[j]; 149 c3[j] = c[j];
135 150
136 - edge new_edge = c3; //create an edge from the given centerline  
137 - unsigned int I = new_edge.size(); //calculate the number of points on the centerline 151 + // edge new_edge = c3; ///This is dangerous.
  152 + edge new_edge(c3);
  153 +
  154 + //create an edge from the given centerline
  155 + unsigned int I = new_edge.size(); //calculate the number of points on the centerline
138 156
139 //get the first and last vertex IDs for the line 157 //get the first and last vertex IDs for the line
140 - std::vector< unsigned > id; //create an array to store the centerline point IDs 158 + std::vector< unsigned > id; //create an array to store the centerline point IDs
141 O.getLinei(l, id); //get the list of point IDs for the line 159 O.getLinei(l, id); //get the list of point IDs for the line
142 i[0] = id.front(); //get the OBJ ID for the first element of the line 160 i[0] = id.front(); //get the OBJ ID for the first element of the line
143 i[1] = id.back(); //get the OBJ ID for the last element of the line 161 i[1] = id.back(); //get the OBJ ID for the last element of the line
144 162
145 - std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array 163 + std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array
146 unsigned it_idx; //create an integer for the id2vert entry index 164 unsigned it_idx; //create an integer for the id2vert entry index
147 165
148 //find out if the nodes for this fiber have already been created 166 //find out if the nodes for this fiber have already been created
149 - it = find(id2vert.begin(), id2vert.end(), i[0]); //look for the first node 167 + it = find(id2vert.begin(), id2vert.end(), i[0]); //look for the first node
150 it_idx = std::distance(id2vert.begin(), it); 168 it_idx = std::distance(id2vert.begin(), it);
151 - if(it == id2vert.end()){ //if i[0] hasn't already been used 169 + if(it == id2vert.end()){ //if i[0] hasn't already been used
152 vertex new_vertex = new_edge[0]; //create a new vertex, assign it a position 170 vertex new_vertex = new_edge[0]; //create a new vertex, assign it a position
153 - new_vertex.e[0].push_back(E.size()); //add the current edge as outgoing  
154 - new_edge.v[0] = V.size(); //add the new vertex to the edge  
155 - V.push_back(new_vertex); //add the new vertex to the vertex list  
156 - id2vert.push_back(i[0]); //add the ID to the ID->vertex conversion list 171 + new_vertex.e[0].push_back(E.size()); //add the current edge as outgoing
  172 + new_edge.v[0] = V.size(); //add the new edge to the edge
  173 + V.push_back(new_vertex); //add the new vertex to the vertex list
  174 + id2vert.push_back(i[0]); //add the ID to the ID->vertex conversion list
157 } 175 }
158 - else{ //if the vertex already exists 176 + else{ //if the vertex already exists
159 V[it_idx].e[0].push_back(E.size()); //add the current edge as outgoing 177 V[it_idx].e[0].push_back(E.size()); //add the current edge as outgoing
160 new_edge.v[0] = it_idx; 178 new_edge.v[0] = it_idx;
161 } 179 }
162 180
163 - it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID 181 + it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID
164 it_idx = std::distance(id2vert.begin(), it); 182 it_idx = std::distance(id2vert.begin(), it);
165 - if(it == id2vert.end()){ //if i[1] hasn't already been used  
166 - vertex new_vertex = new_edge[I-1]; //create a new vertex, assign it a position  
167 - new_vertex.e[1].push_back(E.size()); //add the current edge as incoming 183 + if(it == id2vert.end()){ //if i[1] hasn't already been used
  184 + vertex new_vertex = new_edge[I-1]; //create a new vertex, assign it a position
  185 + new_vertex.e[1].push_back(E.size()); //add the current edge as incoming
168 new_edge.v[1] = V.size(); 186 new_edge.v[1] = V.size();
169 - V.push_back(new_vertex); //add the new vertex to the vertex list  
170 - id2vert.push_back(i[1]); //add the ID to the ID->vertex conversion list 187 + V.push_back(new_vertex); //add the new vertex to the vertex list
  188 + id2vert.push_back(i[1]); //add the ID to the ID->vertex conversion list
171 } 189 }
172 - else{ //if the vertex already exists 190 + else{ //if the vertex already exists
173 V[it_idx].e[1].push_back(E.size()); //add the current edge as incoming 191 V[it_idx].e[1].push_back(E.size()); //add the current edge as incoming
174 new_edge.v[1] = it_idx; 192 new_edge.v[1] = it_idx;
175 } 193 }
176 194
177 - E.push_back(new_edge); //push the edge to the list 195 + E.push_back(new_edge); //push the edge to the list
178 196
179 } 197 }
180 } 198 }
@@ -199,17 +217,17 @@ public: @@ -199,17 +217,17 @@ public:
199 /// This function resamples all fibers in a network given a desired minimum spacing 217 /// This function resamples all fibers in a network given a desired minimum spacing
200 /// @param spacing is the minimum distance between two points on the network 218 /// @param spacing is the minimum distance between two points on the network
201 stim::network<T> resample(T spacing){ 219 stim::network<T> resample(T spacing){
202 - stim::network<T> n; //create a new network that will be an exact copy, with resampled fibers  
203 - n.V = V; //copy all vertices 220 + stim::network<T> n; //create a new network that will be an exact copy, with resampled fibers
  221 + n.V = V; //copy all vertices
204 222
205 - n.E.resize(edges()); //allocate space for the edge list 223 + n.E.resize(edges()); //allocate space for the edge list
206 224
207 //copy all fibers, resampling them in the process 225 //copy all fibers, resampling them in the process
208 - for(unsigned e = 0; e < edges(); e++){ //for each edge in the edge list  
209 - n.E[e] = E[e].resample(spacing); //resample the edge and copy it to the new network 226 + for(unsigned e = 0; e < edges(); e++){ //for each edge in the edge list
  227 + n.E[e] = E[e].resample(spacing); //resample the edge and copy it to the new network
210 } 228 }
211 229
212 - return n; //return the resampled network 230 + return n; //return the resampled network
213 } 231 }
214 232
215 233
@@ -236,14 +254,14 @@ public: @@ -236,14 +254,14 @@ public:
236 /// @param m is the magnitude value to use. The default is 0 (usually radius). 254 /// @param m is the magnitude value to use. The default is 0 (usually radius).
237 T average(unsigned m = 0){ 255 T average(unsigned m = 0){
238 256
239 - T M, L; //allocate space for the total magnitude and length  
240 - M = L = 0; //initialize both the initial magnitude and length to zero  
241 - for(unsigned e = 0; e < E.size(); e++){ //for each edge in the network 257 + T M, L; //allocate space for the total magnitude and length
  258 + M = L = 0; //initialize both the initial magnitude and length to zero
  259 + for(unsigned e = 0; e < E.size(); e++){ //for each edge in the network
242 M += E[e].integrate(m); //get the integrated magnitude 260 M += E[e].integrate(m); //get the integrated magnitude
243 - L += E[e].length(); //get the edge length 261 + L += E[e].length(); //get the edge length
244 } 262 }
245 263
246 - return M / L; //return the average magnitude 264 + return M / L; //return the average magnitude
247 } 265 }
248 266
249 /// This function compares two networks and returns the percentage of the current network that is missing from A. 267 /// This function compares two networks and returns the percentage of the current network that is missing from A.
@@ -256,17 +274,17 @@ public: @@ -256,17 +274,17 @@ public:
256 R = (*this); //initialize the result with the current network 274 R = (*this); //initialize the result with the current network
257 275
258 //generate a KD-tree for network A 276 //generate a KD-tree for network A
259 - float metric = 0.0; // initialize metric to be returned after comparing the networks  
260 - ANNkd_tree* kdt; // initialize a pointer to a kd tree  
261 - double **c; // centerline (array of double pointers) - points on kdtree must be double  
262 - unsigned int n_data = A.total_points(); // set the number of points  
263 - c = (double**) malloc(sizeof(double*) * n_data); // allocate the array pointer  
264 - for(unsigned int i = 0; i < n_data; i++) // allocate space for each point of 3 dimensions 277 + float metric = 0.0; // initialize metric to be returned after comparing the networks
  278 + ANNkd_tree* kdt; // initialize a pointer to a kd tree
  279 + double **c; // centerline (array of double pointers) - points on kdtree must be double
  280 + unsigned int n_data = A.total_points(); // set the number of points
  281 + c = (double**) malloc(sizeof(double*) * n_data); // allocate the array pointer
  282 + for(unsigned int i = 0; i < n_data; i++) // allocate space for each point of 3 dimensions
265 c[i] = (double*) malloc(sizeof(double) * 3); 283 c[i] = (double*) malloc(sizeof(double) * 3);
266 284
267 unsigned t = 0; 285 unsigned t = 0;
268 for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in the network 286 for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in the network
269 - for(unsigned p = 0; p < A.E[e].size(); p++){ //for each point in the edge 287 + for(unsigned p = 0; p < A.E[e].size(); p++){ //for each point in the edge
270 for(unsigned d = 0; d < 3; d++){ //for each coordinate 288 for(unsigned d = 0; d < 3; d++){ //for each coordinate
271 289
272 c[t][d] = A.E[e][p][d]; 290 c[t][d] = A.E[e][p][d];
@@ -276,27 +294,27 @@ public: @@ -276,27 +294,27 @@ public:
276 } 294 }
277 295
278 //compare each point in the current network to the field produced by A 296 //compare each point in the current network to the field produced by A
279 - ANNpointArray pts = (ANNpointArray)c; // create an array of data points of type double  
280 - kdt = new ANNkd_tree(pts, n_data, 3); // build a KD tree using the annpointarray 297 + ANNpointArray pts = (ANNpointArray)c; // create an array of data points of type double
  298 + kdt = new ANNkd_tree(pts, n_data, 3); // build a KD tree using the annpointarray
281 double eps = 0; // error bound 299 double eps = 0; // error bound
282 - ANNdistArray dists = new ANNdist[1]; // near neighbor distances  
283 - ANNidxArray nnIdx = new ANNidx[1]; // near neighbor indices // allocate near neigh indices 300 + ANNdistArray dists = new ANNdist[1]; // near neighbor distances
  301 + ANNidxArray nnIdx = new ANNidx[1]; // near neighbor indices // allocate near neigh indices
284 302
285 stim::vec3<T> p0, p1; 303 stim::vec3<T> p0, p1;
286 float m1; 304 float m1;
287 - float M = 0; //stores the total metric value  
288 - float L = 0; //stores the total network length 305 + float M = 0; //stores the total metric value
  306 + float L = 0; //stores the total network length
289 ANNpoint queryPt = annAllocPt(3); 307 ANNpoint queryPt = annAllocPt(3);
290 for(unsigned e = 0; e < R.E.size(); e++){ //for each edge in A 308 for(unsigned e = 0; e < R.E.size(); e++){ //for each edge in A
291 - R.E[e].add_mag(0); //add a new magnitude for the metric 309 + R.E[e].add_mag(0); //add a new magnitude for the metric
292 310
293 - for(unsigned p = 0; p < R.E[e].size(); p++){ //for each point in the edge 311 + for(unsigned p = 0; p < R.E[e].size(); p++){ //for each point in the edge
294 312
295 - p1 = R.E[e][p]; //get the next point in the edge 313 + p1 = R.E[e][p]; //get the next point in the edge
296 stim2ann(queryPt, p1); 314 stim2ann(queryPt, p1);
297 - kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network 315 + kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network
298 m1 = 1.0f - gaussianFunction((float)dists[0], sigma); //calculate the metric value based on the distance 316 m1 = 1.0f - gaussianFunction((float)dists[0], sigma); //calculate the metric value based on the distance
299 - R.E[e].set_mag(m1, p, 1); //set the error for the second point in the segment 317 + R.E[e].set_mag(m1, p, 1); //set the error for the second point in the segment
300 318
301 } 319 }
302 } 320 }
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 3
4 4
5 #include <stim/cuda/cudatools/callable.h> 5 #include <stim/cuda/cudatools/callable.h>
  6 +#include <cmath>
6 7
7 8
8 namespace stim{ 9 namespace stim{
stim/visualization/gl_aaboundingbox.h
@@ -11,6 +11,9 @@ class gl_aaboundingbox : public aaboundingbox&lt;T&gt;{ @@ -11,6 +11,9 @@ class gl_aaboundingbox : public aaboundingbox&lt;T&gt;{
11 11
12 public: 12 public:
13 13
  14 + using stim::aaboundingbox<T>::A;
  15 + using stim::aaboundingbox<T>::B;
  16 +
14 //default constructor 17 //default constructor
15 gl_aaboundingbox() : stim::aaboundingbox<T>(){} 18 gl_aaboundingbox() : stim::aaboundingbox<T>(){}
16 19
@@ -57,4 +60,4 @@ public: @@ -57,4 +60,4 @@ public:
57 60
58 }; //end namespace stim 61 }; //end namespace stim
59 62
60 -#endif  
61 \ No newline at end of file 63 \ No newline at end of file
  64 +#endif