Commit 797f8ab070316a36aac3ed211e6f5c6532590443
1 parent
4df9ec0e
cleaned up the stim::network comparison calculation
Showing
2 changed files
with
72 additions
and
28 deletions
Show diff stats
stim/biomodels/fiber.h
... | ... | @@ -444,7 +444,7 @@ public: |
444 | 444 | return ss.str(); |
445 | 445 | } |
446 | 446 | /// Returns the number of centerline points in the fiber |
447 | - unsigned int n_pts(){ | |
447 | + unsigned int size(){ | |
448 | 448 | return N; |
449 | 449 | } |
450 | 450 | |
... | ... | @@ -461,7 +461,7 @@ public: |
461 | 461 | return get_vec(N-1); |
462 | 462 | } |
463 | 463 | ////resample a fiber in the network |
464 | - stim::fiber<T> resample(T spacing=25.0) | |
464 | + stim::fiber<T> resample(T spacing) | |
465 | 465 | { |
466 | 466 | |
467 | 467 | |
... | ... | @@ -473,7 +473,7 @@ public: |
473 | 473 | std::vector<stim::vec<T> > fiberPositions = centerline(); |
474 | 474 | std::vector<stim::vec<T> > newPointList; // initialize list of new resampled points on the fiber |
475 | 475 | // for each point on the centerline (skip if it is the last point on centerline) |
476 | - unsigned int N = fiberPositions.size(); // number of points on the fiber | |
476 | + //unsigned int N = fiberPositions.size(); // number of points on the fiber | |
477 | 477 | for(unsigned int f=0; f< N-1; f++) |
478 | 478 | { |
479 | 479 | ... | ... |
stim/biomodels/network.h
... | ... | @@ -44,7 +44,7 @@ class network{ |
44 | 44 | |
45 | 45 | /// Resamples an edge by calling the fiber resampling function |
46 | 46 | edge resample(T spacing){ |
47 | - edge e(fiber<T>::resample()); //call the fiber->edge constructor | |
47 | + edge e(fiber<T>::resample(spacing)); //call the fiber->edge constructor | |
48 | 48 | e.v[0] = v[0]; //copy the vertex data |
49 | 49 | e.v[1] = v[1]; |
50 | 50 | |
... | ... | @@ -238,10 +238,13 @@ class network{ |
238 | 238 | |
239 | 239 | |
240 | 240 | // total number of points on all fibers after resampling -- function used only on a resampled network |
241 | - unsigned int total_points(){ | |
242 | - unsigned int n = points_afterResampling().size(); | |
241 | + unsigned total_points(){ | |
242 | + unsigned n = 0; | |
243 | + for(unsigned e = 0; e < E.size(); e++) | |
244 | + n += E[e].size(); | |
245 | + //unsigned int n = points_afterResampling().size(); | |
243 | 246 | return n; |
244 | - } | |
247 | + } | |
245 | 248 | |
246 | 249 | // gaussian function |
247 | 250 | float gaussianFunction(float x, float std=25){ return exp(-x/(2*std*std));} // by default std = 25 |
... | ... | @@ -264,40 +267,84 @@ class network{ |
264 | 267 | return sqrt(sum); |
265 | 268 | } |
266 | 269 | |
270 | + void stim2ann(ANNpoint &a, stim::vec<T> b){ | |
271 | + a[0] = b[0]; | |
272 | + a[1] = b[1]; | |
273 | + a[2] = b[2]; | |
274 | + } | |
275 | + | |
267 | 276 | |
268 | 277 | /// This function compares two networks and returns a metric |
269 | - float compare(stim::network<T> networkTruth, float sigma){ | |
278 | + float compare(stim::network<T> A, float sigma){ | |
270 | 279 | float metric = 0.0; // initialize metric to be returned after comparing the networks |
271 | 280 | ANNkd_tree* kdt; // initialize a pointer to a kd tree |
272 | 281 | double **c; // centerline (array of double pointers) - points on kdtree must be double |
273 | 282 | unsigned int n_data = total_points(); // set the number of points |
274 | 283 | c = (double**) malloc(sizeof(double*) * n_data); // allocate the array pointer |
275 | 284 | for(unsigned int i = 0; i < n_data; i++) // allocate space for each point of 3 dimensions |
276 | - {c[i] = (double*) malloc(sizeof(double) * 3);} | |
277 | - std::vector<stim::vec<T> > pointsVector = points_afterResampling(); //get vertices in the network after resampling | |
278 | - for(unsigned int i = 0; i < n_data; i++) // loop through all the vertices after resampling | |
279 | - { | |
280 | - for(unsigned int d = 0; d < 3; d++){ // for each dimension | |
281 | - c[i][d] = double(pointsVector[i][d]); // copy the coordinate and convert_to_double | |
285 | + c[i] = (double*) malloc(sizeof(double) * 3); | |
286 | + //std::vector<stim::vec<T> > pointsVector = points_afterResampling(); //get vertices in the network after resampling | |
287 | + unsigned t = 0; | |
288 | + for(unsigned e = 0; e < E.size(); e++){ //for each edge in the network | |
289 | + for(unsigned p = 0; p < E[e].size(); p++){ //for each point in the edge | |
290 | + for(unsigned d = 0; d < 3; d++){ //for each coordinate | |
291 | + | |
292 | + c[t][d] = E[e][p][d]; | |
282 | 293 | } |
294 | + t++; | |
283 | 295 | } |
296 | + } | |
297 | + | |
284 | 298 | ANNpointArray pts = (ANNpointArray)c; // create an array of data points of type double |
285 | 299 | kdt = new ANNkd_tree(pts, n_data, 3); // build a KD tree using the annpointarray |
286 | 300 | double eps = 0; // error bound |
287 | - ANNdistArray dists1;dists1 = new ANNdist[1]; // near neighbor distances | |
288 | - ANNdistArray dists2; dists2 = new ANNdist[1]; // near neighbor distances | |
289 | - ANNidxArray nnIdx1; nnIdx1 = new ANNidx[1]; // near neighbor indices // allocate near neigh indices | |
290 | - ANNidxArray nnIdx2; nnIdx2 = new ANNidx[1]; // near neighbor indices // allocate near neigh indices | |
291 | - int N; // number of points on the fiber in the second network | |
292 | - float totalNetworkLength = networkTruth.lengthOfNetwork(); | |
293 | - stim::vec<float> fiberMetric(networkTruth.edges()); // allocate space for accumulating fiber metric as each fiber is evaluated | |
301 | + ANNdistArray dists = new ANNdist[1]; // near neighbor distances | |
302 | + ANNidxArray nnIdx = new ANNidx[1]; // near neighbor indices // allocate near neigh indices | |
303 | + | |
304 | + stim::vec<T> p0, p1; | |
305 | + float m0, m1; | |
306 | + float M = 0; //stores the total metric value | |
307 | + float l; //stores the segment length | |
308 | + float L = 0; //stores the total network length | |
309 | + ANNpoint queryPt = annAllocPt(3); | |
310 | + for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in A | |
311 | + M = 0; //total metric value for the fiber | |
312 | + p0 = A.E[e][0]; //get the first point in the edge | |
313 | + stim2ann(queryPt, p0); | |
314 | + kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network | |
315 | + m0 = 1.0f - gaussianFunction(dists[0], sigma); //calculate the metric value based on the distance | |
316 | + | |
317 | + for(unsigned p = 1; p < A.E[e].size(); p++){ //for each point in the edge | |
318 | + | |
319 | + p1 = A.E[e][p]; //get the next point in the edge | |
320 | + stim2ann(queryPt, p1); | |
321 | + kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network | |
322 | + m1 = 1.0f - gaussianFunction(dists[0], sigma); //calculate the metric value based on the distance | |
323 | + | |
324 | + //average the metric and scale | |
325 | + l = (p1 - p0).len(); //calculate the length of the segment | |
326 | + L += l; //add the length of this segment to the total network length | |
327 | + M += (m0 + m1)/2 * l; //scale the metric based on segment length | |
328 | + | |
329 | + //swap points | |
330 | + p0 = p1; | |
331 | + m0 = m1; | |
332 | + } | |
333 | + } | |
334 | + | |
335 | + return M/L; | |
336 | + | |
337 | + | |
338 | + /*int N; // number of points on the fiber in the second network | |
339 | + float totalNetworkLength = A.lengthOfNetwork(); | |
340 | + stim::vec<float> fiberMetric(A.edges()); // allocate space for accumulating fiber metric as each fiber is evaluated | |
294 | 341 | stim::fiber<T> FIBER; // Initialize a fiber will be used in calculating the metric |
295 | 342 | //for each fiber in the second network, find nearest distance in the kd tree |
296 | - for (unsigned int i=0; i < networkTruth.edges(); i ++) // loop through all the edges/fibers in the network | |
343 | + for (unsigned int i=0; i < A.edges(); i ++) // loop through all the edges/fibers in the network | |
297 | 344 | { |
298 | - FIBER = networkTruth.get_fiber(i); // Get the fiber corresponding to the index i | |
345 | + FIBER = A.get_fiber(i); // Get the fiber corresponding to the index i | |
299 | 346 | std::vector< stim::vec<T> > fiberPoints = FIBER.centerline(); // Get the points on the fiber |
300 | - N = FIBER.n_pts(); // number of points on the fiber | |
347 | + N = FIBER.size(); // number of points on the fiber | |
301 | 348 | stim::vec<float> segmentMetric(N-1); // allocate space for a vec array that stores metric for each segmen in the fiber |
302 | 349 | // for each segment in the fiber |
303 | 350 | for (unsigned j = 0; j < N - 1; j++) |
... | ... | @@ -317,15 +364,12 @@ class network{ |
317 | 364 | float error1 = 1.0f - gaussianFunction(float(dists1[0]), sigma);float error2 = 1.0f - gaussianFunction(float(dists2[0]), sigma); |
318 | 365 | // average the error and scale it with distance between the points |
319 | 366 | segmentMetric[j] = ((error1 + error2) / 2) * dist(p1, p2) ; |
320 | - /*segmentDists[j] = dist(p1, p2); */ | |
321 | 367 | } |
322 | 368 | fiberMetric[i] = sum(segmentMetric); |
323 | - /*distsList[i] = sum(segmentDists);*/ | |
324 | 369 | } |
325 | - /*assert (sum(distsList)==totalNetworkLength);*/ | |
326 | 370 | metric = sum(fiberMetric)/totalNetworkLength; //normalize the scaled error of all the points with total length of the network |
327 | 371 | assert (0<=metric <=1); //assert metroc os always less than or equal to one and greater than or equal to zero |
328 | - return metric; | |
372 | + return metric;*/ | |
329 | 373 | } |
330 | 374 | }; //end stim::network class |
331 | 375 | }; //end stim namespace | ... | ... |